diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include')
217 files changed, 10792 insertions, 5586 deletions
diff --git a/contrib/llvm/tools/clang/include/clang-c/Index.h b/contrib/llvm/tools/clang/include/clang-c/Index.h index edd3cbb..aa3403c 100644 --- a/contrib/llvm/tools/clang/include/clang-c/Index.h +++ b/contrib/llvm/tools/clang/include/clang-c/Index.h @@ -23,6 +23,34 @@ #include "clang-c/Platform.h" #include "clang-c/CXString.h" +/** + * \brief The version constants for the libclang API. + * CINDEX_VERSION_MINOR should increase when there are API additions. + * CINDEX_VERSION_MAJOR is intended for "major" source/ABI breaking changes. + * + * The policy about the libclang API was always to keep it source and ABI + * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. + */ +#define CINDEX_VERSION_MAJOR 0 +#define CINDEX_VERSION_MINOR 6 + +#define CINDEX_VERSION_ENCODE(major, minor) ( \ + ((major) * 10000) \ + + ((minor) * 1)) + +#define CINDEX_VERSION CINDEX_VERSION_ENCODE( \ + CINDEX_VERSION_MAJOR, \ + CINDEX_VERSION_MINOR ) + +#define CINDEX_VERSION_STRINGIZE_(major, minor) \ + #major"."#minor +#define CINDEX_VERSION_STRINGIZE(major, minor) \ + CINDEX_VERSION_STRINGIZE_(major, minor) + +#define CINDEX_VERSION_STRING CINDEX_VERSION_STRINGIZE( \ + CINDEX_VERSION_MAJOR, \ + CINDEX_VERSION_MINOR) + #ifdef __cplusplus extern "C" { #endif @@ -383,7 +411,7 @@ CINDEX_LINKAGE unsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2); /** - * \brief Returns non-zero if \arg range is null. + * \brief Returns non-zero if \p range is null. */ CINDEX_LINKAGE int clang_Range_isNull(CXSourceRange range); @@ -1035,13 +1063,15 @@ enum CXTranslationUnit_Flags { * code-completion operations. */ CXTranslationUnit_CacheCompletionResults = 0x08, + /** - * \brief DEPRECATED: Enable precompiled preambles in C++. + * \brief Used to indicate that the translation unit will be serialized with + * \c clang_saveTranslationUnit. * - * Note: this is a *temporary* option that is available only while - * we are testing C++ precompiled preamble support. It is deprecated. + * This option is typically used when parsing a header with the intent of + * producing a precompiled header. */ - CXTranslationUnit_CXXPrecompiledPreamble = 0x10, + CXTranslationUnit_ForSerialization = 0x10, /** * \brief DEPRECATED: Enabled chained precompiled preambles in C++. @@ -1904,9 +1934,10 @@ enum CXCursorKind { */ CXCursor_ReturnStmt = 214, - /** \brief A GNU inline assembly statement extension. + /** \brief A GCC inline assembly statement extension. */ - CXCursor_AsmStmt = 215, + CXCursor_GCCAsmStmt = 215, + CXCursor_AsmStmt = CXCursor_GCCAsmStmt, /** \brief Objective-C's overall \@try-\@catch-\@finally statement. */ @@ -2009,7 +2040,15 @@ enum CXCursorKind { CXCursor_MacroInstantiation = CXCursor_MacroExpansion, CXCursor_InclusionDirective = 503, CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective, - CXCursor_LastPreprocessing = CXCursor_InclusionDirective + CXCursor_LastPreprocessing = CXCursor_InclusionDirective, + + /* Extra Declarations */ + /** + * \brief A module import declaration. + */ + CXCursor_ModuleImportDecl = 600, + CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl, + CXCursor_LastExtraDecl = CXCursor_ModuleImportDecl }; /** @@ -2040,7 +2079,8 @@ typedef struct { * \brief A comment AST node. */ typedef struct { - const void *Data; + const void *ASTNode; + CXTranslationUnit TranslationUnit; } CXComment; /** @@ -2068,9 +2108,9 @@ CINDEX_LINKAGE CXCursor clang_getTranslationUnitCursor(CXTranslationUnit); CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor); /** - * \brief Returns non-zero if \arg cursor is null. + * \brief Returns non-zero if \p cursor is null. */ -CINDEX_LINKAGE int clang_Cursor_isNull(CXCursor); +CINDEX_LINKAGE int clang_Cursor_isNull(CXCursor cursor); /** * \brief Compute a hash value for the given cursor. @@ -2585,6 +2625,7 @@ enum CXCallingConv { CXCallingConv_X86Pascal = 5, CXCallingConv_AAPCS = 6, CXCallingConv_AAPCS_VFP = 7, + CXCallingConv_PnaclCall = 8, CXCallingConv_Invalid = 100, CXCallingConv_Unexposed = 200 @@ -3164,6 +3205,12 @@ CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(CXCursor); CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C); /** + * \brief Given a cursor pointing to an ObjC message, returns the CXType of the + * receiver. + */ +CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C); + +/** * \brief Given a cursor that represents a declaration, return the associated * comment's source range. The range may include multiple consecutive comments * with whitespace in between. @@ -3195,6 +3242,65 @@ CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C); */ /** + * \defgroup CINDEX_MODULE Module introspection + * + * The functions in this group provide access to information about modules. + * + * @{ + */ + +typedef void *CXModule; + +/** + * \brief Given a CXCursor_ModuleImportDecl cursor, return the associated module. + */ +CINDEX_LINKAGE CXModule clang_Cursor_getModule(CXCursor C); + +/** + * \param Module a module object. + * + * \returns the parent of a sub-module or NULL if the given module is top-level, + * e.g. for 'std.vector' it will return the 'std' module. + */ +CINDEX_LINKAGE CXModule clang_Module_getParent(CXModule Module); + +/** + * \param Module a module object. + * + * \returns the name of the module, e.g. for the 'std.vector' sub-module it + * will return "vector". + */ +CINDEX_LINKAGE CXString clang_Module_getName(CXModule Module); + +/** + * \param Module a module object. + * + * \returns the full name of the module, e.g. "std.vector". + */ +CINDEX_LINKAGE CXString clang_Module_getFullName(CXModule Module); + +/** + * \param Module a module object. + * + * \returns the number of top level headers associated with this module. + */ +CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXModule Module); + +/** + * \param Module a module object. + * + * \param Index top level header index (zero-based). + * + * \returns the specified top level header associated with the module. + */ +CINDEX_LINKAGE +CXFile clang_Module_getTopLevelHeader(CXModule Module, unsigned Index); + +/** + * @} + */ + +/** * \defgroup CINDEX_COMMENT Comment AST introspection * * The routines in this group provide access to information in the @@ -3272,7 +3378,7 @@ enum CXCommentKind { * \brief A \\param or \\arg command that describes the function parameter * (name, passing direction, description). * - * \brief For example: \\param [in] ParamName description. + * For example: \\param [in] ParamName description. */ CXComment_ParamCommand = 7, @@ -3280,7 +3386,7 @@ enum CXCommentKind { * \brief A \\tparam command that describes a template parameter (name and * description). * - * \brief For example: \\tparam T description. + * For example: \\tparam T description. */ CXComment_TParamCommand = 8, @@ -3379,7 +3485,7 @@ CINDEX_LINKAGE unsigned clang_Comment_getNumChildren(CXComment Comment); /** * \param Comment AST node of any kind. * - * \param ArgIdx argument index (zero-based). + * \param ChildIdx child index (zero-based). * * \returns the specified child of the AST node. */ @@ -3692,14 +3798,11 @@ CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment); * A Relax NG schema for the XML can be found in comment-xml-schema.rng file * inside clang source tree. * - * \param TU the translation unit \c Comment belongs to. - * * \param Comment a \c CXComment_FullComment AST node. * * \returns string containing an XML document. */ -CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXTranslationUnit TU, - CXComment Comment); +CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment); /** * @} @@ -4323,8 +4426,7 @@ clang_getCompletionAnnotation(CXCompletionString completion_string, * \param completion_string The code completion string whose parent is * being queried. * - * \param kind If non-NULL, will be set to the kind of the parent context, - * or CXCursor_NotImplemented if there is no context. + * \param kind DEPRECATED: always set to CXCursor_NotImplemented if non-NULL. * * \returns The name of the completion parent, e.g., "NSObject" if * the completion string represents a method in the NSObject class. @@ -4917,22 +5019,35 @@ typedef struct { CXFile file; int isImport; int isAngled; + /** + * \brief Non-zero if the directive was automatically turned into a module + * import. + */ + int isModuleImport; } CXIdxIncludedFileInfo; /** * \brief Data for IndexerCallbacks#importedASTFile. */ typedef struct { + /** + * \brief Top level AST file containing the imported PCH, module or submodule. + */ CXFile file; /** - * \brief Location where the file is imported. It is useful mostly for - * modules. + * \brief The imported module or NULL if the AST file is a PCH. + */ + CXModule module; + /** + * \brief Location where the file is imported. Applicable only for modules. */ CXIdxLoc loc; /** - * \brief Non-zero if the AST file is a module otherwise it's a PCH. + * \brief Non-zero if an inclusion directive was automatically turned into + * a module import. Applicable only for modules. */ - int isModule; + int isImplicit; + } CXIdxImportedASTFileInfo; typedef enum { @@ -4965,7 +5080,8 @@ typedef enum { CXIdxEntity_CXXConstructor = 22, CXIdxEntity_CXXDestructor = 23, CXIdxEntity_CXXConversionFunction = 24, - CXIdxEntity_CXXTypeAlias = 25 + CXIdxEntity_CXXTypeAlias = 25, + CXIdxEntity_CXXInterface = 26 } CXIdxEntityKind; @@ -5183,8 +5299,8 @@ typedef struct { * * AST files will not get indexed (there will not be callbacks to index all * the entities in an AST file). The recommended action is that, if the AST - * file is not already indexed, to block further indexing and initiate a new - * indexing job specific to the AST file. + * file is not already indexed, to initiate a new indexing job specific to + * the AST file. */ CXIdxClientASTFile (*importedASTFile)(CXClientData client_data, const CXIdxImportedASTFileInfo *); diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h index 86a6cbb..cce8661 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h @@ -12,6 +12,7 @@ #include "clang/ARCMigrate/FileRemapper.h" #include "clang/Frontend/CompilerInvocation.h" +#include "clang/Basic/SourceLocation.h" namespace clang { class ASTContext; @@ -51,7 +52,7 @@ bool applyTransformations(CompilerInvocation &origCI, DiagnosticConsumer *DiagClient); /// \brief Applies automatic modifications and produces temporary files -/// and metadata into the \arg outputDir path. +/// and metadata into the \p 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 @@ -68,7 +69,7 @@ bool migrateWithTemporaryFiles(CompilerInvocation &origCI, bool emitPremigrationARCErrors, StringRef plistOut); -/// \brief Get the set of file remappings from the \arg outputDir path that +/// \brief Get the set of file remappings from the \p outputDir path that /// migrateWithTemporaryFiles produced. /// /// \returns false if no error is produced, true otherwise. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h b/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h index 69a3866..37b0740 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h @@ -19,12 +19,14 @@ namespace clang { class CXXRecordDecl; class DeclGroupRef; class HandleTagDeclDefinition; + class PPMutationListener; class ASTMutationListener; class ASTDeserializationListener; // layering violation because void* is ugly class SemaConsumer; // layering violation required for safe SemaConsumer class TagDecl; class VarDecl; class FunctionDecl; + class ImportDecl; /// ASTConsumer - This is an abstract interface that should be implemented by /// clients that read ASTs. This abstraction layer allows the client to be @@ -79,6 +81,11 @@ public: /// The default implementation ignored them. virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D); + /// \brief Handle an ImportDecl that was implicitly created due to an + /// inclusion directive. + /// The default implementation passes it to HandleTopLevelDecl. + virtual void HandleImplicitImportDecl(ImportDecl *D); + /// CompleteTentativeDefinition - Callback invoked at the end of a translation /// unit to notify the consumer that the given tentative definition should be /// completed. @@ -105,6 +112,11 @@ public: /// it was actually used. virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {} + /// \brief If the consumer is interested in preprocessor entities getting + /// modified after their initial creation, it should return a pointer to + /// a PPMutationListener here. + virtual PPMutationListener *GetPPMutationListener() { return 0; } + /// \brief If the consumer is interested in entities getting modified after /// their initial creation, it should return a pointer to /// an ASTMutationListener here. @@ -118,9 +130,6 @@ public: /// PrintStats - If desired, print any statistics. virtual void PrintStats() {} - - // Support isa/cast/dyn_cast - static bool classof(const ASTConsumer *) { return true; } }; } // end namespace clang. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h index cad3ad2..f0934b7 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h @@ -6,9 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the ASTContext interface. -// +/// +/// \file +/// \brief Defines the clang::ASTContext interface. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_ASTCONTEXT_H @@ -28,6 +29,7 @@ #include "clang/AST/Type.h" #include "clang/AST/CanonicalType.h" #include "clang/AST/RawCommentList.h" +#include "clang/AST/CommentCommandTraits.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -84,8 +86,8 @@ namespace clang { class FullComment; } -/// ASTContext - This class holds long-lived AST nodes (such as types and -/// decls) that can be referred to throughout the semantic analysis of a file. +/// \brief Holds long-lived AST nodes (such as types and decls) that can be +/// referred to throughout the semantic analysis of a file. class ASTContext : public RefCountedBase<ASTContext> { ASTContext &this_() { return *this; } @@ -144,19 +146,20 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable NestedNameSpecifier *GlobalNestedNameSpecifier; friend class NestedNameSpecifier; - /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts. - /// This is lazily created. This is intentionally not serialized. + /// \brief A cache mapping from RecordDecls to ASTRecordLayouts. + /// + /// This is lazily created. This is intentionally not serialized. mutable llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*> ASTRecordLayouts; mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*> ObjCLayouts; - /// TypeInfoMap - A cache from types to size and alignment information. + /// \brief A cache from types to size and alignment information. typedef llvm::DenseMap<const Type*, std::pair<uint64_t, unsigned> > TypeInfoMap; mutable TypeInfoMap MemoizedTypeInfo; - /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions. + /// \brief A cache mapping from CXXRecordDecls to key functions. llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions; /// \brief Mapping from ObjCContainers to their ObjCImplementations. @@ -170,7 +173,7 @@ class ASTContext : public RefCountedBase<ASTContext> { llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits; /// \brief Mapping from class scope functions specialization to their - /// template patterns. + /// template patterns. llvm::DenseMap<const FunctionDecl*, FunctionDecl*> ClassScopeSpecializationPattern; @@ -206,17 +209,20 @@ class ASTContext : public RefCountedBase<ASTContext> { /// __builtin_va_list type. mutable TypedefDecl *BuiltinVaListDecl; - /// \brief The typedef for the predefined 'id' type. + /// \brief The typedef for the predefined \c id type. mutable TypedefDecl *ObjCIdDecl; - /// \brief The typedef for the predefined 'SEL' type. + /// \brief The typedef for the predefined \c SEL type. mutable TypedefDecl *ObjCSelDecl; - /// \brief The typedef for the predefined 'Class' type. + /// \brief The typedef for the predefined \c Class type. mutable TypedefDecl *ObjCClassDecl; - /// \brief The typedef for the predefined 'Protocol' class in Objective-C. + /// \brief The typedef for the predefined \c Protocol class in Objective-C. mutable ObjCInterfaceDecl *ObjCProtocolClassDecl; + + /// \brief The typedef for the predefined 'BOOL' type. + mutable TypedefDecl *BOOLDecl; // Typedefs which may be provided defining the structure of Objective-C // pseudo-builtins @@ -296,9 +302,10 @@ class ASTContext : public RefCountedBase<ASTContext> { InstantiatedFromStaticDataMember; /// \brief Keeps track of the declaration from which a UsingDecl was - /// created during instantiation. The source declaration is always - /// a UsingDecl, an UnresolvedUsingValueDecl, or an - /// UnresolvedUsingTypenameDecl. + /// created during instantiation. + /// + /// The source declaration is always a UsingDecl, an UnresolvedUsingValueDecl, + /// or an UnresolvedUsingTypenameDecl. /// /// For example: /// \code @@ -337,9 +344,8 @@ class ASTContext : public RefCountedBase<ASTContext> { /// mangling context. llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts; - /// \brief Mapping that stores parameterIndex values for ParmVarDecls - /// when that value exceeds the bitfield size of - /// ParmVarDeclBits.ParameterIndex. + /// \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; @@ -348,10 +354,10 @@ class ASTContext : public RefCountedBase<ASTContext> { TranslationUnitDecl *TUDecl; - /// SourceMgr - The associated SourceManager object. + /// \brief The associated SourceManager object.a SourceManager &SourceMgr; - /// LangOpts - The language options used to create the AST associated with + /// \brief The language options used to create the AST associated with /// this ASTContext object. LangOptions &LangOpts; @@ -387,9 +393,11 @@ public: OwningPtr<ExternalASTSource> ExternalSource; ASTMutationListener *Listener; - clang::PrintingPolicy getPrintingPolicy() const { return PrintingPolicy; } + const clang::PrintingPolicy &getPrintingPolicy() const { + return PrintingPolicy; + } - void setPrintingPolicy(clang::PrintingPolicy Policy) { + void setPrintingPolicy(const clang::PrintingPolicy &Policy) { PrintingPolicy = Policy; } @@ -508,6 +516,8 @@ public: } void addComment(const RawComment &RC) { + assert(LangOpts.RetainCommentsFromSystemHeaders || + !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin())); Comments.addComment(RC, BumpAlloc); } @@ -522,7 +532,22 @@ public: /// Return parsed documentation comment attached to a given declaration. /// Returns NULL if no comment is attached. - comments::FullComment *getCommentForDecl(const Decl *D) const; + /// + /// \param PP the Preprocessor used with this TU. Could be NULL if + /// preprocessor is not available. + comments::FullComment *getCommentForDecl(const Decl *D, + const Preprocessor *PP) const; + + comments::FullComment *cloneFullComment(comments::FullComment *FC, + const Decl *D) const; + +private: + mutable comments::CommandTraits CommentCommandTraits; + +public: + comments::CommandTraits &getCommentCommandTraits() const { + return CommentCommandTraits; + } /// \brief Retrieve the attributes for the given declaration. AttrVec& getDeclAttrs(const Decl *D); @@ -547,7 +572,7 @@ public: TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation = SourceLocation()); - /// \brief If the given using decl is an instantiation of a + /// \brief If the given using decl \p Inst is an instantiation of a /// (possibly unresolved) using decl from a template instantiation, /// return it. NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst); @@ -564,28 +589,28 @@ public: void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl); - /// ZeroBitfieldFollowsNonBitfield - return 'true" if 'FD' is a zero-length - /// bitfield which follows the non-bitfield 'LastFD'. + /// \brief Return \c true if \p FD is a zero-length bitfield which follows + /// the non-bitfield \p LastFD. bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; - /// ZeroBitfieldFollowsBitfield - return 'true" if 'FD' is a zero-length - /// bitfield which follows the bitfield 'LastFD'. + /// \brief Return \c true if \p FD is a zero-length bitfield which follows + /// the bitfield \p LastFD. bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; - /// BitfieldFollowsBitfield - return 'true" if 'FD' is a - /// bitfield which follows the bitfield 'LastFD'. + /// \brief Return \c true if \p FD is a bitfield which follows the bitfield + /// \p LastFD. bool BitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; - /// NonBitfieldFollowsBitfield - return 'true" if 'FD' is not a - /// bitfield which follows the bitfield 'LastFD'. + /// \brief Return \c true if \p FD is not a bitfield which follows the + /// bitfield \p LastFD. bool NonBitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; - /// BitfieldFollowsNonBitfield - return 'true" if 'FD' is a - /// bitfield which follows the none bitfield 'LastFD'. + /// \brief Return \c true if \p FD is a bitfield which follows the + /// non-bitfield \p LastFD. bool BitfieldFollowsNonBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; @@ -603,6 +628,17 @@ public: /// Overridden method. void addOverriddenMethod(const CXXMethodDecl *Method, const CXXMethodDecl *Overridden); + + /// \brief Return C++ or ObjC overridden methods for the given \p Method. + /// + /// An ObjC method is considered to override any method in the class's + /// base classes, its protocols, or its categories' protocols, that has + /// the same selector and is of the same kind (class or instance). + /// A method in an implementation is not considered as overriding the same + /// method in the interface or its categories. + void getOverriddenMethods( + const NamedDecl *Method, + SmallVectorImpl<const NamedDecl *> &Overridden) const; /// \brief Notify the AST context that a new import declaration has been /// parsed or implicitly created within this translation unit. @@ -673,6 +709,7 @@ public: CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; CanQualType VoidPtrTy, NullPtrTy; CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; CanQualType ObjCBuiltinBoolTy; @@ -731,77 +768,85 @@ public: //===--------------------------------------------------------------------===// private: - /// getExtQualType - Return a type with extended qualifiers. + /// \brief Return a type with extended qualifiers. QualType getExtQualType(const Type *Base, Qualifiers Quals) const; QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const; public: - /// getAddSpaceQualType - Return the uniqued reference to the type for an - /// address space qualified type with the specified type and address space. + /// \brief Return the uniqued reference to the type for an address space + /// qualified type with the specified type and address space. + /// /// The resulting type has a union of the qualifiers from T and the address /// space. If T already has an address space specifier, it is silently /// replaced. QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const; - /// getObjCGCQualType - Returns the uniqued reference to the type for an - /// objc gc qualified type. The retulting type has a union of the qualifiers - /// from T and the gc attribute. + /// \brief Return the uniqued reference to the type for an Objective-C + /// gc-qualified type. + /// + /// The retulting type has a union of the qualifiers from T and the gc + /// attribute. QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const; - /// getRestrictType - Returns the uniqued reference to the type for a - /// 'restrict' qualified type. The resulting type has a union of the - /// qualifiers from T and 'restrict'. + /// \brief Return the uniqued reference to the type for a \c restrict + /// qualified type. + /// + /// The resulting type has a union of the qualifiers from \p T and + /// \c restrict. QualType getRestrictType(QualType T) const { return T.withFastQualifiers(Qualifiers::Restrict); } - /// getVolatileType - Returns the uniqued reference to the type for a - /// 'volatile' qualified type. The resulting type has a union of the - /// qualifiers from T and 'volatile'. + /// \brief Return the uniqued reference to the type for a \c volatile + /// qualified type. + /// + /// The resulting type has a union of the qualifiers from \p T and + /// \c volatile. QualType getVolatileType(QualType T) const { return T.withFastQualifiers(Qualifiers::Volatile); } - /// getConstType - Returns the uniqued reference to the type for a - /// 'const' qualified type. The resulting type has a union of the - /// qualifiers from T and 'const'. + /// \brief Return the uniqued reference to the type for a \c const + /// qualified type. /// - /// It can be reasonably expected that this will always be - /// equivalent to calling T.withConst(). + /// The resulting type has a union of the qualifiers from \p T and \c const. + /// + /// It can be reasonably expected that this will always be equivalent to + /// calling T.withConst(). QualType getConstType(QualType T) const { return T.withConst(); } - /// adjustFunctionType - Change the ExtInfo on a function type. + /// \brief Change the ExtInfo on a function type. const FunctionType *adjustFunctionType(const FunctionType *Fn, FunctionType::ExtInfo EInfo); - /// getComplexType - Return the uniqued reference to the type for a complex + /// \brief Return the uniqued reference to the type for a complex /// number with the specified element type. QualType getComplexType(QualType T) const; CanQualType getComplexType(CanQualType T) const { return CanQualType::CreateUnsafe(getComplexType((QualType) T)); } - /// getPointerType - Return the uniqued reference to the type for a pointer to + /// \brief Return the uniqued reference to the type for a pointer to /// the specified type. QualType getPointerType(QualType T) const; CanQualType getPointerType(CanQualType T) const { return CanQualType::CreateUnsafe(getPointerType((QualType) T)); } - /// getAtomicType - Return the uniqued reference to the atomic type for - /// the specified type. + /// \brief 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. + /// \brief Return the uniqued reference to the type for a block of the + /// specified type. QualType getBlockPointerType(QualType T) const; - /// This gets the struct used to keep track of the descriptor for pointer to + /// Gets the struct used to keep track of the descriptor for pointer to /// blocks. QualType getBlockDescriptorType() const; - /// This gets the struct used to keep track of the extended descriptor for + /// Gets the struct used to keep track of the extended descriptor for /// pointer to blocks. QualType getBlockDescriptorExtendedType() const; @@ -812,78 +857,82 @@ public: return cudaConfigureCallDecl; } - /// This builds the struct used for __block variables. + /// Builds the struct used for __block variables. QualType BuildByRefType(StringRef DeclName, QualType Ty) const; /// Returns true iff we need copy/dispose helpers for the given type. bool BlockRequiresCopying(QualType Ty) const; - /// getLValueReferenceType - Return the uniqued reference to the type for an - /// lvalue reference to the specified type. + /// \brief Return the uniqued reference to the type for an lvalue reference + /// to the specified type. QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true) const; - /// getRValueReferenceType - Return the uniqued reference to the type for an - /// rvalue reference to the specified type. + /// \brief Return the uniqued reference to the type for an rvalue reference + /// to the specified type. QualType getRValueReferenceType(QualType T) const; - /// getMemberPointerType - Return the uniqued reference to the type for a - /// member pointer to the specified type in the specified class. The class - /// is a Type because it could be a dependent name. + /// \brief Return the uniqued reference to the type for a member pointer to + /// the specified type in the specified class. + /// + /// The class \p Cls is a \c Type because it could be a dependent name. QualType getMemberPointerType(QualType T, const Type *Cls) const; - /// getVariableArrayType - Returns a non-unique reference to the type for a - /// variable array of the specified element type. + /// \brief Return a non-unique reference to the type for a variable array of + /// the specified element type. QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const; - /// getDependentSizedArrayType - Returns a non-unique reference to - /// the type for a dependently-sized array of the specified element - /// type. FIXME: We will need these to be uniqued, or at least - /// comparable, at some point. + /// \brief Return a non-unique reference to the type for a dependently-sized + /// array of the specified element type. + /// + /// FIXME: We will need these to be uniqued, or at least comparable, at some + /// point. QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const; - /// getIncompleteArrayType - Returns a unique reference to the type for a - /// incomplete array of the specified element type. + /// \brief Return a unique reference to the type for an incomplete array of + /// the specified element type. QualType getIncompleteArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; - /// getConstantArrayType - Return the unique reference to the type for a - /// constant array of the specified element type. + /// \brief Return the unique reference to the type for a constant array of + /// the specified element type. QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; - /// getVariableArrayDecayedType - Returns a vla type where known sizes - /// are replaced with [*]. + /// \brief Returns a vla type where known sizes are replaced with [*]. QualType getVariableArrayDecayedType(QualType Ty) const; - /// getVectorType - Return the unique reference to a vector type of - /// the specified element type and size. VectorType must be a built-in type. + /// \brief Return the unique reference to a vector type of the specified + /// element type and size. + /// + /// \pre \p VectorType must be a built-in type. QualType getVectorType(QualType VectorType, unsigned NumElts, VectorType::VectorKind VecKind) const; - /// getExtVectorType - Return the unique reference to an extended vector type - /// of the specified element type and size. VectorType must be a built-in - /// type. + /// \brief Return the unique reference to an extended vector type + /// of the specified element type and size. + /// + /// \pre \p VectorType must be a built-in type. QualType getExtVectorType(QualType VectorType, unsigned NumElts) const; - /// getDependentSizedExtVectorType - Returns a non-unique reference to - /// the type for a dependently-sized vector of the specified element - /// type. FIXME: We will need these to be uniqued, or at least - /// comparable, at some point. + /// \pre Return a non-unique reference to the type for a dependently-sized + /// vector of the specified element type. + /// + /// FIXME: We will need these to be uniqued, or at least comparable, at some + /// point. QualType getDependentSizedExtVectorType(QualType VectorType, Expr *SizeExpr, SourceLocation AttrLoc) const; - /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. - /// + /// \brief Return a K&R style C function type like 'int()'. QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const; @@ -891,14 +940,13 @@ public: return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo()); } - /// getFunctionType - Return a normal function type with a typed - /// argument list. + /// \brief Return a normal function type with a typed argument list. QualType getFunctionType(QualType ResultTy, const QualType *Args, unsigned NumArgs, const FunctionProtoType::ExtProtoInfo &EPI) const; - /// getTypeDeclType - Return the unique reference to the type for - /// the specified type declaration. + /// \brief Return the unique reference to the type for the specified type + /// declaration. QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl = 0) const { assert(Decl && "Passed null for Decl param"); @@ -913,8 +961,8 @@ public: return getTypeDeclTypeSlow(Decl); } - /// getTypedefType - Return the unique reference to the type for the - /// specified typedef-name decl. + /// \brief Return the unique reference to the type for the specified + /// typedef-name decl. QualType getTypedefType(const TypedefNameDecl *Decl, QualType Canon = QualType()) const; @@ -986,69 +1034,75 @@ public: ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) const; - /// getObjCObjectPointerType - Return a ObjCObjectPointerType type - /// for the given ObjCObjectType. + /// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType. QualType getObjCObjectPointerType(QualType OIT) const; - /// getTypeOfType - GCC extension. + /// \brief GCC extension. QualType getTypeOfExprType(Expr *e) const; QualType getTypeOfType(QualType t) const; - /// getDecltypeType - C++0x decltype. + /// \brief C++11 decltype. QualType getDecltypeType(Expr *e, QualType UnderlyingType) const; - /// getUnaryTransformType - unary type transforms + /// \brief Unary type transforms QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType, UnaryTransformType::UTTKind UKind) const; - /// getAutoType - C++0x deduced auto type. + /// \brief C++11 deduced auto type. QualType getAutoType(QualType DeducedType) const; - /// getAutoDeductType - C++0x deduction pattern for 'auto' type. + /// \brief C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; - /// getAutoRRefDeductType - C++0x deduction pattern for 'auto &&' type. + /// \brief C++11 deduction pattern for 'auto &&' type. QualType getAutoRRefDeductType() const; - /// getTagDeclType - Return the unique reference to the type for the - /// specified TagDecl (struct/union/class/enum) decl. + /// \brief Return the unique reference to the type for the specified TagDecl + /// (struct/union/class/enum) decl. QualType getTagDeclType(const TagDecl *Decl) const; - /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined - /// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4). + /// \brief Return the unique type for "size_t" (C99 7.17), defined in + /// <stddef.h>. + /// + /// The sizeof operator requires this (C99 6.5.3.4p4). CanQualType getSizeType() const; - /// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5), - /// defined in <stdint.h>. + /// \brief Return the unique type for "intmax_t" (C99 7.18.1.5), defined in + /// <stdint.h>. CanQualType getIntMaxType() const; - /// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5), - /// defined in <stdint.h>. + /// \brief Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in + /// <stdint.h>. CanQualType getUIntMaxType() const; - /// getWCharType - In C++, this returns the unique wchar_t type. In C99, this + /// \brief In C++, this returns the unique wchar_t type. In C99, this /// returns a type compatible with the type defined in <stddef.h> as defined /// by the target. QualType getWCharType() const { return WCharTy; } - /// getSignedWCharType - Return the type of "signed wchar_t". + /// \brief Return the type of "signed wchar_t". + /// /// Used when in C++, as a GCC extension. QualType getSignedWCharType() const; - /// getUnsignedWCharType - Return the type of "unsigned wchar_t". + /// \brief Return the type of "unsigned wchar_t". + /// /// Used when in C++, as a GCC extension. QualType getUnsignedWCharType() const; - /// getWIntType - In C99, this returns a type compatible with the type + /// \brief In C99, this returns a type compatible with the type /// defined in <stddef.h> as defined by the target. QualType getWIntType() const { return WIntTy; } - /// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17) - /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). + /// \brief Return the unique type for "ptrdiff_t" (C99 7.17) defined in + /// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). QualType getPointerDiffType() const; - // getCFConstantStringType - Return the C structure type used to represent - // constant CFStrings. + /// \brief Return the unique type for "pid_t" defined in + /// <sys/types.h>. We need this to compute the correct type for vfork(). + QualType getProcessIDType() const; + + /// \brief Return the C structure type used to represent constant CFStrings. QualType getCFConstantStringType() const; /// Get the structure type used to representation CFStrings, or NULL @@ -1074,21 +1128,21 @@ public: ObjCNSStringType = T; } - /// \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. + /// \brief Retrieve the type that \c id has been defined to, which may be + /// different from the built-in \c id if \c id has been typedef'd. QualType getObjCIdRedefinitionType() const { if (ObjCIdRedefinitionType.isNull()) return getObjCIdType(); return ObjCIdRedefinitionType; } - /// \brief Set the user-written type that redefines 'id'. + /// \brief Set the user-written type that redefines \c id. void setObjCIdRedefinitionType(QualType RedefType) { ObjCIdRedefinitionType = RedefType; } - /// \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. + /// \brief Retrieve the type that \c Class has been defined to, which may be + /// different from the built-in \c Class if \c Class has been typedef'd. QualType getObjCClassRedefinitionType() const { if (ObjCClassRedefinitionType.isNull()) return getObjCClassType(); @@ -1175,27 +1229,29 @@ public: return getLangOpts().CPlusPlus ? BoolTy : IntTy; } - /// getObjCEncodingForType - Emit the ObjC type encoding for the - /// given type into \arg S. If \arg NameFields is specified then - /// record field names are also encoded. - void getObjCEncodingForType(QualType t, std::string &S, + /// \brief Emit the Objective-CC type encoding for the given type \p T into + /// \p S. + /// + /// If \p Field is specified then record field names are also encoded. + void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=0) const; void getLegacyIntegralTypeEncoding(QualType &t) const; - // Put the string version of type qualifiers into S. + /// \brief Put the string version of the type qualifiers \p QT into \p S. void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, std::string &S) const; - /// getObjCEncodingForFunctionDecl - Returns the encoded type for this - /// function. This is in the same format as Objective-C method encodings. + /// \brief Emit the encoded type for the function \p Decl into \p S. + /// + /// This is in the same format as Objective-C method encodings. /// /// \returns true if an error occurred (e.g., because one of the parameter /// types is incomplete), false otherwise. bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S); - /// getObjCEncodingForMethodDecl - Return the encoded type for this method - /// declaration. + /// \brief Emit the encoded type for the method declaration \p Decl into + /// \p S. /// /// \returns true if an error occurred (e.g., because one of the parameter /// types is incomplete), false otherwise. @@ -1203,8 +1259,7 @@ public: bool Extended = false) const; - /// getObjCEncodingForBlock - Return the encoded type for this block - /// declaration. + /// \brief Return the encoded type for this block declaration. std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const; /// getObjCEncodingForPropertyDecl - Return the encoded type for @@ -1218,16 +1273,18 @@ public: bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, ObjCProtocolDecl *rProto) const; - /// getObjCEncodingTypeSize returns size of type for objective-c encoding - /// purpose in characters. - CharUnits getObjCEncodingTypeSize(QualType t) const; + /// \brief Return the size of type \p T for Objective-C encoding purpose, + /// in characters. + CharUnits getObjCEncodingTypeSize(QualType T) const; - /// \brief Retrieve the typedef corresponding to the predefined 'id' type + /// \brief Retrieve the typedef corresponding to the predefined \c 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. + /// \brief Represents the Objective-CC \c id type. + /// + /// This is set up lazily, by Sema. \c id is always a (typedef for a) + /// pointer type, a pointer to a struct. QualType getObjCIdType() const { return getTypeDeclType(getObjCIdDecl()); } @@ -1246,48 +1303,64 @@ public: /// 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. + /// \brief Represents the Objective-C \c Class type. + /// + /// This is set up lazily, by Sema. \c Class is always a (typedef for a) + /// pointer type, a pointer to a struct. QualType getObjCClassType() const { return getTypeDeclType(getObjCClassDecl()); } /// \brief Retrieve the Objective-C class declaration corresponding to - /// the predefined 'Protocol' class. + /// the predefined \c Protocol class. ObjCInterfaceDecl *getObjCProtocolDecl() const; + + /// \brief Retrieve declaration of 'BOOL' typedef + TypedefDecl *getBOOLDecl() const { + return BOOLDecl; + } + + /// \brief Save declaration of 'BOOL' typedef + void setBOOLDecl(TypedefDecl *TD) { + BOOLDecl = TD; + } + + /// \brief type of 'BOOL' type. + QualType getBOOLType() const { + return getTypeDeclType(getBOOLDecl()); + } - /// \brief Retrieve the type of the Objective-C "Protocol" class. + /// \brief Retrieve the type of the Objective-C \c Protocol class. QualType getObjCProtoType() const { return getObjCInterfaceType(getObjCProtocolDecl()); } /// \brief Retrieve the C type declaration corresponding to the predefined - /// __builtin_va_list type. + /// \c __builtin_va_list type. TypedefDecl *getBuiltinVaListDecl() const; - /// \brief Retrieve the type of the __builtin_va_list type. + /// \brief Retrieve the type of the \c __builtin_va_list type. QualType getBuiltinVaListType() const { return getTypeDeclType(getBuiltinVaListDecl()); } /// \brief Retrieve the C type declaration corresponding to the predefined - /// __va_list_tag type used to help define the __builtin_va_list type for - /// some targets. + /// \c __va_list_tag type used to help define the \c __builtin_va_list type + /// for some targets. QualType getVaListTagType() const; - /// getCVRQualifiedType - Returns a type with additional const, - /// volatile, or restrict qualifiers. + /// \brief Return a type with additional \c const, \c volatile, or + /// \c restrict qualifiers. QualType getCVRQualifiedType(QualType T, unsigned CVR) const { return getQualifiedType(T, Qualifiers::fromCVRMask(CVR)); } - /// getQualifiedType - Un-split a SplitQualType. + /// \brief Un-split a SplitQualType. QualType getQualifiedType(SplitQualType split) const { return getQualifiedType(split.Ty, split.Quals); } - /// getQualifiedType - Returns a type with additional qualifiers. + /// \brief Return a type with additional qualifiers. QualType getQualifiedType(QualType T, Qualifiers Qs) const { if (!Qs.hasNonFastQualifiers()) return T.withFastQualifiers(Qs.getFastQualifiers()); @@ -1296,15 +1369,16 @@ public: return getExtQualType(Ptr, Qc); } - /// getQualifiedType - Returns a type with additional qualifiers. + /// \brief Return a type with additional qualifiers. QualType getQualifiedType(const Type *T, Qualifiers Qs) const { if (!Qs.hasNonFastQualifiers()) return QualType(T, Qs.getFastQualifiers()); return getExtQualType(T, Qs); } - /// getLifetimeQualifiedType - Returns a type with the given - /// lifetime qualifier. + /// \brief Return a type with the given lifetime qualifier. + /// + /// \pre Neither type.ObjCLifetime() nor \p lifetime may be \c OCL_None. QualType getLifetimeQualifiedType(QualType type, Qualifiers::ObjCLifetime lifetime) { assert(type.getObjCLifetime() == Qualifiers::OCL_None); @@ -1341,8 +1415,9 @@ public: GE_Missing_ucontext ///< Missing a type from <ucontext.h> }; - /// GetBuiltinType - Return the type for the specified builtin. If - /// IntegerConstantArgs is non-null, it is filled in with a bitmask of + /// \brief Return the type for the specified builtin. + /// + /// If \p IntegerConstantArgs is non-null, it is filled in with a bitmask of /// arguments to the builtin that are required to be integer constant /// expressions. QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, @@ -1357,19 +1432,19 @@ private: //===--------------------------------------------------------------------===// public: - /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's - /// garbage collection attribute. - /// + /// \brief Return one of the GCNone, Weak or Strong Objective-C garbage + /// collection attributes. Qualifiers::GC getObjCGCAttrKind(QualType Ty) const; - /// areCompatibleVectorTypes - Return true if the given vector types - /// are of the same unqualified type or if they are equivalent to the same - /// GCC vector type, ignoring whether they are target-specific (AltiVec or - /// Neon) types. + /// \brief Return true if the given vector types are of the same unqualified + /// type or if they are equivalent to the same GCC vector type. + /// + /// \note This ignores whether they are target-specific (AltiVec or Neon) + /// types. bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec); - /// isObjCNSObjectType - Return true if this is an NSObject object with - /// its NSObject attribute set. + /// \brief Return true if this is an \c NSObject object with its \c NSObject + /// attribute set. static bool isObjCNSObjectType(QualType Ty) { return Ty->isObjCNSObjectType(); } @@ -1378,19 +1453,17 @@ public: // Type Sizing and Analysis //===--------------------------------------------------------------------===// - /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified - /// scalar floating point type. + /// \brief Return the APFloat 'semantics' for the specified scalar floating + /// point type. const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const; - /// getTypeInfo - Get the size and alignment of the specified complete type in - /// bits. + /// \brief Get the size and alignment of the specified complete type in bits. std::pair<uint64_t, unsigned> getTypeInfo(const Type *T) const; std::pair<uint64_t, unsigned> getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); } - /// getTypeSize - Return the size of the specified type, in bits. This method - /// does not work on incomplete types. + /// \brief Return the size of the specified (complete) type \p T, in bits. uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).first; } @@ -1398,24 +1471,24 @@ public: return getTypeInfo(T).first; } - /// getCharWidth - Return the size of the character type, in bits + /// \brief Return the size of the character type, in bits. uint64_t getCharWidth() const { return getTypeSize(CharTy); } - /// toCharUnitsFromBits - Convert a size in bits to a size in characters. + /// \brief Convert a size in bits to a size in characters. CharUnits toCharUnitsFromBits(int64_t BitSize) const; - /// toBits - Convert a size in characters to a size in bits. + /// \brief Convert a size in characters to a size in bits. int64_t toBits(CharUnits CharSize) const; - /// getTypeSizeInChars - Return the size of the specified type, in characters. - /// This method does not work on incomplete types. + /// \brief Return the size of the specified (complete) type \p T, in + /// characters. CharUnits getTypeSizeInChars(QualType T) const; CharUnits getTypeSizeInChars(const Type *T) const; - /// getTypeAlign - Return the ABI-specified alignment of a type, in bits. - /// This method does not work on incomplete types. + /// \brief Return the ABI-specified alignment of a (complete) type \p T, in + /// bits. unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).second; } @@ -1423,49 +1496,59 @@ public: return getTypeInfo(T).second; } - /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in - /// characters. This method does not work on incomplete types. + /// \brief Return the ABI-specified alignment of a (complete) type \p T, in + /// characters. CharUnits getTypeAlignInChars(QualType T) const; CharUnits getTypeAlignInChars(const Type *T) const; + + // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the + // type is a record, its data size is returned. + std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const; std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const; std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const; - /// getPreferredTypeAlign - Return the "preferred" alignment of the specified - /// type for the current target in bits. This can be different than the ABI - /// alignment in cases where it is beneficial for performance to overalign - /// a data type. + /// \brief Return the "preferred" alignment of the specified type \p T for + /// the current target, in bits. + /// + /// This can be different than the ABI alignment in cases where it is + /// beneficial for performance to overalign a data type. unsigned getPreferredTypeAlign(const Type *T) const; - /// getDeclAlign - Return a conservative estimate of the alignment of - /// the specified decl. Note that bitfields do not have a valid alignment, so - /// this method will assert on them. - /// If @p RefAsPointee, references are treated like their underlying type + /// \brief Return a conservative estimate of the alignment of the specified + /// decl \p D. + /// + /// \pre \p D must not be a bitfield type, as bitfields do not have a valid + /// alignment. + /// + /// If \p RefAsPointee, references are treated like their underlying type /// (for alignof), else they're treated like pointers (for CodeGen). CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false) const; - /// getASTRecordLayout - Get or compute information about the layout of the - /// specified record (struct/union/class), which indicates its size and field + /// \brief Get or compute information about the layout of the specified + /// record (struct/union/class) \p D, which indicates its size and field /// position information. const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const; - /// getASTObjCInterfaceLayout - Get or compute information about the - /// layout of the specified Objective-C interface. + /// \brief Get or compute information about the layout of the specified + /// Objective-C interface. const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const; void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS, bool Simple = false) const; - /// getASTObjCImplementationLayout - Get or compute information about - /// the layout of the specified Objective-C implementation. This may - /// differ from the interface if synthesized ivars are present. + /// \brief Get or compute information about the layout of the specified + /// Objective-C implementation. + /// + /// This may differ from the interface if synthesized ivars are present. const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const; - /// getKeyFunction - Get the key function for the given record decl, or NULL - /// if there isn't one. The key function is, according to the Itanium C++ ABI - /// section 5.2.3: + /// \brief Get the key function for the given record decl, or NULL if there + /// isn't one. + /// + /// The key function is, according to the Itanium C++ ABI section 5.2.3: /// /// ...the first non-pure virtual function that is not inline at the point /// of class definition. @@ -1489,12 +1572,14 @@ public: // Type Operators //===--------------------------------------------------------------------===// - /// getCanonicalType - Return the canonical (structural) type corresponding to - /// the specified potentially non-canonical type. The non-canonical version - /// of a type may have many "decorated" versions of types. Decorators can - /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed - /// to be free of any of these, allowing two canonical types to be compared - /// for exact equality with a simple pointer comparison. + /// \brief Return the canonical (structural) type corresponding to the + /// specified potentially non-canonical type \p T. + /// + /// The non-canonical version of a type may have many "decorated" versions of + /// types. Decorators can include typedefs, 'typeof' operators, etc. The + /// returned type is guaranteed to be free of any of these, allowing two + /// canonical types to be compared for exact equality with a simple pointer + /// comparison. CanQualType getCanonicalType(QualType T) const { return CanQualType::CreateUnsafe(T.getCanonicalType()); } @@ -1503,21 +1588,23 @@ public: return T->getCanonicalTypeInternal().getTypePtr(); } - /// getCanonicalParamType - Return the canonical parameter type - /// corresponding to the specific potentially non-canonical one. + /// \brief Return the canonical parameter type corresponding to the specific + /// potentially non-canonical one. + /// /// Qualifiers are stripped off, functions are turned into function /// pointers, and arrays decay one level into pointers. CanQualType getCanonicalParamType(QualType T) const; - /// \brief Determine whether the given types are equivalent. + /// \brief Determine whether the given types \p T1 and \p T2 are equivalent. bool hasSameType(QualType T1, QualType T2) const { return getCanonicalType(T1) == getCanonicalType(T2); } - /// \brief Returns this type as a completely-unqualified array type, - /// capturing the qualifiers in Quals. This will remove the minimal amount of - /// sugaring from the types, similar to the behavior of - /// QualType::getUnqualifiedType(). + /// \brief Return this type as a completely-unqualified array type, + /// capturing the qualifiers in \p Quals. + /// + /// This will remove the minimal amount of sugaring from the types, similar + /// to the behavior of QualType::getUnqualifiedType(). /// /// \param T is the qualified type, which may be an ArrayType /// @@ -1628,15 +1715,16 @@ public: return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T)); } - /// getBaseElementType - Returns the innermost element type of an array type. + /// \brief Return the innermost element type of an array type. + /// /// For example, will return "int" for int[m][n] QualType getBaseElementType(const ArrayType *VAT) const; - /// getBaseElementType - Returns the innermost element type of a type - /// (which needn't actually be an array type). + /// \brief Return the innermost element type of a type (which needn't + /// actually be an array type). QualType getBaseElementType(QualType QT) const; - /// getConstantArrayElementCount - Returns number of constant array elements. + /// \brief Return number of constant array elements. uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const; /// \brief Perform adjustment on the parameter type of a function. @@ -1651,21 +1739,22 @@ public: /// cv-qualifiers. QualType getSignatureParameterType(QualType T) const; - /// getArrayDecayedType - Return the properly qualified result of decaying the - /// specified array type to a pointer. This operation is non-trivial when - /// handling typedefs etc. The canonical type of "T" must be an array type, - /// this returns a pointer to a properly qualified element of the array. + /// \brief Return the properly qualified result of decaying the specified + /// array type to a pointer. + /// + /// This operation is non-trivial when handling typedefs etc. The canonical + /// type of \p T must be an array type, this returns a pointer to a properly + /// qualified element of the array. /// /// See C99 6.7.5.3p7 and C99 6.3.2.1p3. QualType getArrayDecayedType(QualType T) const; - /// getPromotedIntegerType - Returns the type that Promotable will - /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable - /// integer type. + /// \brief Return the type that \p PromotableType will promote to: C99 + /// 6.3.1.1p2, assuming that \p PromotableType is a promotable integer type. QualType getPromotedIntegerType(QualType PromotableType) const; - /// \brief Recurses in pointer/array types until it finds an objc retainable - /// type and returns its ownership. + /// \brief Recurses in pointer/array types until it finds an Objective-C + /// retainable type and returns its ownership. Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const; /// \brief Whether this is a promotable bitfield reference according @@ -1675,21 +1764,24 @@ public: /// promotion occurs. QualType isPromotableBitField(Expr *E) const; - /// getIntegerTypeOrder - Returns the highest ranked integer type: - /// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If - /// LHS < RHS, return -1. + /// \brief Return the highest ranked integer type, see C99 6.3.1.8p1. + /// + /// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If + /// \p LHS < \p RHS, return -1. int getIntegerTypeOrder(QualType LHS, QualType RHS) const; - /// getFloatingTypeOrder - Compare the rank of the two specified floating - /// point types, ignoring the domain of the type (i.e. 'double' == - /// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If - /// LHS < RHS, return -1. + /// \brief Compare the rank of the two specified floating point types, + /// ignoring the domain of the type (i.e. 'double' == '_Complex double'). + /// + /// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If + /// \p LHS < \p RHS, return -1. int getFloatingTypeOrder(QualType LHS, QualType RHS) const; - /// getFloatingTypeOfSizeWithinDomain - Returns a real floating - /// point or a complex type (based on typeDomain/typeSize). - /// 'typeDomain' is a real floating point or complex type. - /// 'typeSize' is a real floating point or complex type. + /// \brief Return a real floating point or a complex type (based on + /// \p typeDomain/\p typeSize). + /// + /// \param typeDomain a real floating point or complex type. + /// \param typeSize a real floating point or complex type. QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize, QualType typeDomain) const; @@ -1787,7 +1879,7 @@ public: // Per C99 6.2.5p6, for every signed integer type, there is a corresponding // unsigned integer type. This method takes a signed type, and returns the // corresponding unsigned integer type. - QualType getCorrespondingUnsignedType(QualType T); + QualType getCorrespondingUnsignedType(QualType T) const; //===--------------------------------------------------------------------===// // Type Iterators. @@ -1805,8 +1897,8 @@ public: // Integer Values //===--------------------------------------------------------------------===// - /// MakeIntValue - Make an APSInt of the appropriate width and - /// signedness for the given \arg Value and integer \arg Type. + /// \brief Make an APSInt of the appropriate width and signedness for the + /// given \p Value and integer \p Type. llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const { llvm::APSInt Res(getIntWidth(Type), !Type->isSignedIntegerOrEnumerationType()); @@ -1816,12 +1908,14 @@ public: bool isSentinelNullExpr(const Expr *E); - /// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists. + /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if + /// none exists. ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D); - /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists. + /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if + /// none exists. ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); - /// \brief returns true if there is at least one \@implementation in TU. + /// \brief Return true if there is at least one \@implementation in the TU. bool AnyObjCImplementation() { return !ObjCImpls.empty(); } @@ -1834,7 +1928,7 @@ public: ObjCCategoryImplDecl *ImplD); /// \brief Get the duplicate declaration of a ObjCMethod in the same - /// interface, or null if non exists. + /// interface, or null if none exists. const ObjCMethodDecl *getObjCMethodRedeclaration( const ObjCMethodDecl *MD) const { return ObjCMethodRedecls.lookup(MD); @@ -1846,16 +1940,16 @@ public: ObjCMethodRedecls[MD] = Redecl; } - /// \brief Returns the objc interface that \arg ND belongs to if it is a - /// objc method/property/ivar etc. that is part of an interface, + /// \brief Returns the Objective-C interface that \p ND belongs to if it is + /// an Objective-C method/property/ivar etc. that is part of an interface, /// otherwise returns null. ObjCInterfaceDecl *getObjContainingInterface(NamedDecl *ND) const; /// \brief Set the copy inialization expression of a block var decl. void setBlockVarCopyInits(VarDecl*VD, Expr* Init); - /// \brief Get the copy initialization expression of VarDecl,or NULL if - /// none exists. - Expr *getBlockVarCopyInits(const VarDecl*VD); + /// \brief Get the copy initialization expression of the VarDecl \p VD, or + /// NULL if none exists. + Expr *getBlockVarCopyInits(const VarDecl* VD); /// \brief Allocate an uninitialized TypeSourceInfo. /// @@ -1882,9 +1976,9 @@ public: /// \brief Add a deallocation callback that will be invoked when the /// ASTContext is destroyed. /// - /// \brief Callback A callback function that will be invoked on destruction. + /// \param Callback A callback function that will be invoked on destruction. /// - /// \brief Data Pointer data that will be provided to the callback function + /// \param Data Pointer data that will be provided to the callback function /// when it is called. void AddDeallocation(void (*Callback)(void*), void *Data); @@ -1957,8 +2051,8 @@ public: static unsigned NumImplicitDestructorsDeclared; private: - ASTContext(const ASTContext&); // DO NOT IMPLEMENT - void operator=(const ASTContext&); // DO NOT IMPLEMENT + ASTContext(const ASTContext &) LLVM_DELETED_FUNCTION; + void operator=(const ASTContext &) LLVM_DELETED_FUNCTION; public: /// \brief Initialize built-in types. @@ -1974,7 +2068,7 @@ public: private: void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); - // Return the ObjC type encoding for a given type. + // Return the Objective-C type encoding for a given type. void getObjCEncodingForTypeImpl(QualType t, std::string &S, bool ExpandPointedToStructures, bool ExpandStructures, @@ -2017,13 +2111,13 @@ private: void ReleaseDeclContextMaps(); }; -/// @brief Utility function for constructing a nullary selector. +/// \brief Utility function for constructing a nullary selector. 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. +/// \brief Utility function for constructing an unary selector. 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/ASTMutationListener.h b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h index cb038a0..56d1526 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h @@ -13,6 +13,8 @@ #ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H #define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H +#include "clang/Basic/SourceLocation.h" + namespace clang { class Decl; class DeclContext; diff --git a/contrib/llvm/tools/clang/include/clang/AST/Attr.h b/contrib/llvm/tools/clang/include/clang/AST/Attr.h index b17bd48..12a9855 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Attr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Attr.h @@ -107,9 +107,6 @@ public: // Pretty print this attribute. virtual void printPretty(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const = 0; - - // Implement isa/cast/dyncast/etc. - static bool classof(const Attr *) { return true; } }; class InheritableAttr : public Attr { @@ -125,7 +122,6 @@ public: static bool classof(const Attr *A) { return A->getKind() <= attr::LAST_INHERITABLE; } - static bool classof(const InheritableAttr *) { return true; } }; class InheritableParamAttr : public InheritableAttr { @@ -139,7 +135,6 @@ public: static bool classof(const Attr *A) { return A->getKind() <= attr::LAST_INHERITABLE_PARAM; } - static bool classof(const InheritableParamAttr *) { return true; } }; #include "clang/AST/Attrs.inc" diff --git a/contrib/llvm/tools/clang/include/clang/AST/BuiltinTypes.def b/contrib/llvm/tools/clang/include/clang/AST/BuiltinTypes.def index 34e6fc5..ba322fb 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/BuiltinTypes.def +++ b/contrib/llvm/tools/clang/include/clang/AST/BuiltinTypes.def @@ -206,6 +206,8 @@ PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy) // unknown type, most notably explicit casts. PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy) +PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy) + // The type of a cast which, in ARC, would normally require a // __bridge, but which might be okay depending on the immediate // context. diff --git a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h index ee6eba7..87bdbe0 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h @@ -19,7 +19,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include <list> @@ -271,15 +271,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, SmallVector<UniqueVirtualMethod, 4> > - Overrides; + typedef SmallVector<UniqueVirtualMethod, 4> ValuesT; + typedef llvm::MapVector<unsigned, ValuesT> MapType; + MapType Overrides; public: // Iterate over the set of subobjects that have overriding methods. - typedef llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> > - ::iterator iterator; - typedef llvm::DenseMap<unsigned, SmallVector<UniqueVirtualMethod, 4> > - ::const_iterator const_iterator; + typedef MapType::iterator iterator; + typedef MapType::const_iterator const_iterator; iterator begin() { return Overrides.begin(); } const_iterator begin() const { return Overrides.begin(); } iterator end() { return Overrides.end(); } @@ -357,8 +356,8 @@ public: /// 0 represents the virtua base class subobject of that type, while /// subobject numbers greater than 0 refer to non-virtual base class /// subobjects of that type. -class CXXFinalOverriderMap - : public llvm::DenseMap<const CXXMethodDecl *, OverridingMethods> { }; +class CXXFinalOverriderMap + : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { }; /// \brief A set of all the primary bases for a class. class CXXIndirectPrimaryBaseSet diff --git a/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h b/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h index 6cce888..ea307bf 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h @@ -276,6 +276,7 @@ public: LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType) diff --git a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h index 5be3582..12e74b3 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h @@ -164,8 +164,8 @@ namespace clang { QuantityType getQuantity() const { return Quantity; } /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is - /// greater than or equal to this quantity and is a multiple of \arg - /// Align. Align must be non-zero. + /// greater than or equal to this quantity and is a multiple of \p Align. + /// Align must be non-zero. CharUnits RoundUpToAlignment(const CharUnits &Align) { return CharUnits(llvm::RoundUpToAlignment(Quantity, Align.Quantity)); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Comment.h b/contrib/llvm/tools/clang/include/clang/AST/Comment.h index 01aaac3..316a180 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Comment.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Comment.h @@ -16,6 +16,8 @@ #include "clang/Basic/SourceLocation.h" #include "clang/AST/Type.h" +#include "clang/AST/CommentCommandTraits.h" +#include "clang/AST/DeclObjC.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" @@ -25,7 +27,7 @@ class ParmVarDecl; class TemplateParameterList; namespace comments { - +class FullComment; /// Any part of the comment. /// Abstract class. class Comment { @@ -74,8 +76,9 @@ protected: unsigned : NumInlineContentCommentBits; unsigned RenderKind : 2; + unsigned CommandID : 8; }; - enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 1 }; + enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 }; class HTMLStartTagCommentBitfields { friend class HTMLStartTagComment; @@ -101,10 +104,19 @@ protected: }; enum { NumParagraphCommentBits = NumCommentBits + 2 }; + class BlockCommandCommentBitfields { + friend class BlockCommandComment; + + unsigned : NumCommentBits; + + unsigned CommandID : 8; + }; + enum { NumBlockCommandCommentBits = NumCommentBits + 8 }; + class ParamCommandCommentBitfields { friend class ParamCommandComment; - unsigned : NumCommentBits; + unsigned : NumBlockCommandCommentBits; /// Parameter passing direction, see ParamCommandComment::PassDirection. unsigned Direction : 2; @@ -112,7 +124,7 @@ protected: /// True if direction was specified explicitly in the comment. unsigned IsDirectionExplicit : 1; }; - enum { NumParamCommandCommentBits = 11 }; + enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 }; union { CommentBitfields CommentBits; @@ -121,6 +133,7 @@ protected: InlineCommandCommentBitfields InlineCommandCommentBits; HTMLStartTagCommentBitfields HTMLStartTagCommentBits; ParagraphCommentBitfields ParagraphCommentBits; + BlockCommandCommentBitfields BlockCommandCommentBits; ParamCommandCommentBitfields ParamCommandCommentBits; }; @@ -158,10 +171,9 @@ public: const char *getCommentKindName() const; LLVM_ATTRIBUTE_USED void dump() const; - LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const; - void dump(llvm::raw_ostream &OS, SourceManager *SM) const; - - static bool classof(const Comment *) { return true; } + LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const; + void dump(llvm::raw_ostream &OS, const CommandTraits *Traits, + const SourceManager *SM) const; SourceRange getSourceRange() const LLVM_READONLY { return Range; } @@ -204,8 +216,6 @@ public: C->getCommentKind() <= LastInlineContentCommentConstant; } - static bool classof(const InlineContentComment *) { return true; } - void addTrailingNewline() { InlineContentCommentBits.HasTrailingNewline = 1; } @@ -232,8 +242,6 @@ public: return C->getCommentKind() == TextCommentKind; } - static bool classof(const TextComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -273,35 +281,35 @@ public: }; protected: - /// Command name. - StringRef Name; - /// Command arguments. llvm::ArrayRef<Argument> Args; public: InlineCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name, + unsigned CommandID, RenderKind RK, llvm::ArrayRef<Argument> Args) : InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd), - Name(Name), Args(Args) { + Args(Args) { InlineCommandCommentBits.RenderKind = RK; + InlineCommandCommentBits.CommandID = CommandID; } static bool classof(const Comment *C) { return C->getCommentKind() == InlineCommandCommentKind; } - static bool classof(const InlineCommandComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } - StringRef getCommandName() const { - return Name; + unsigned getCommandID() const { + return InlineCommandCommentBits.CommandID; + } + + StringRef getCommandName(const CommandTraits &Traits) const { + return Traits.getCommandInfo(getCommandID())->Name; } SourceRange getCommandNameRange() const { @@ -352,8 +360,6 @@ public: C->getCommentKind() <= LastHTMLTagCommentConstant; } - static bool classof(const HTMLTagComment *) { return true; } - StringRef getTagName() const LLVM_READONLY { return TagName; } SourceRange getTagNameSourceRange() const LLVM_READONLY { @@ -419,8 +425,6 @@ public: return C->getCommentKind() == HTMLStartTagCommentKind; } - static bool classof(const HTMLStartTagComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -476,8 +480,6 @@ public: return C->getCommentKind() == HTMLEndTagCommentKind; } - static bool classof(const HTMLEndTagComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -498,8 +500,6 @@ public: return C->getCommentKind() >= FirstBlockContentCommentConstant && C->getCommentKind() <= LastBlockContentCommentConstant; } - - static bool classof(const BlockContentComment *) { return true; } }; /// A single paragraph that contains inline content. @@ -529,8 +529,6 @@ public: return C->getCommentKind() == ParagraphCommentKind; } - static bool classof(const ParagraphComment *) { return true; } - child_iterator child_begin() const { return reinterpret_cast<child_iterator>(Content.begin()); } @@ -566,9 +564,6 @@ public: }; protected: - /// Command name. - StringRef Name; - /// Word-like arguments. llvm::ArrayRef<Argument> Args; @@ -578,21 +573,21 @@ protected: BlockCommandComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : + unsigned CommandID) : BlockContentComment(K, LocBegin, LocEnd), - Name(Name), Paragraph(NULL) { - setLocation(getCommandNameRange().getBegin()); + setLocation(getCommandNameBeginLoc()); + BlockCommandCommentBits.CommandID = CommandID; } public: BlockCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : + unsigned CommandID) : BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd), - Name(Name), Paragraph(NULL) { - setLocation(getCommandNameRange().getBegin()); + setLocation(getCommandNameBeginLoc()); + BlockCommandCommentBits.CommandID = CommandID; } static bool classof(const Comment *C) { @@ -600,8 +595,6 @@ public: C->getCommentKind() <= LastBlockCommandCommentConstant; } - static bool classof(const BlockCommandComment *) { return true; } - child_iterator child_begin() const { return reinterpret_cast<child_iterator>(&Paragraph); } @@ -610,12 +603,21 @@ public: return reinterpret_cast<child_iterator>(&Paragraph + 1); } - StringRef getCommandName() const { - return Name; + unsigned getCommandID() const { + return BlockCommandCommentBits.CommandID; } - SourceRange getCommandNameRange() const { - return SourceRange(getLocStart().getLocWithOffset(1), + StringRef getCommandName(const CommandTraits &Traits) const { + return Traits.getCommandInfo(getCommandID())->Name; + } + + SourceLocation getCommandNameBeginLoc() const { + return getLocStart().getLocWithOffset(1); + } + + SourceRange getCommandNameRange(const CommandTraits &Traits) const { + StringRef Name = getCommandName(Traits); + return SourceRange(getCommandNameBeginLoc(), getLocStart().getLocWithOffset(1 + Name.size())); } @@ -667,8 +669,9 @@ public: ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : - BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, Name), + unsigned CommandID) : + BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, + CommandID), ParamIndex(InvalidParamIndex) { ParamCommandCommentBits.Direction = In; ParamCommandCommentBits.IsDirectionExplicit = false; @@ -678,8 +681,6 @@ public: return C->getCommentKind() == ParamCommandCommentKind; } - static bool classof(const ParamCommandComment *) { return true; } - enum PassDirection { In, Out, @@ -705,7 +706,9 @@ public: return getNumArgs() > 0; } - StringRef getParamName() const { + StringRef getParamName(const FullComment *FC) const; + + StringRef getParamNameAsWritten() const { return Args[0].Text; } @@ -748,21 +751,21 @@ private: public: TParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : - BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, Name) + unsigned CommandID) : + BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID) { } static bool classof(const Comment *C) { return C->getCommentKind() == TParamCommandCommentKind; } - static bool classof(const TParamCommandComment *) { return true; } - bool hasParamName() const { return getNumArgs() > 0; } - StringRef getParamName() const { + StringRef getParamName(const FullComment *FC) const; + + StringRef getParamNameAsWritten() const { return Args[0].Text; } @@ -807,8 +810,6 @@ public: return C->getCommentKind() == VerbatimBlockLineCommentKind; } - static bool classof(const VerbatimBlockLineComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -830,17 +831,15 @@ protected: public: VerbatimBlockComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) : + unsigned CommandID) : BlockCommandComment(VerbatimBlockCommentKind, - LocBegin, LocEnd, Name) + LocBegin, LocEnd, CommandID) { } static bool classof(const Comment *C) { return C->getCommentKind() == VerbatimBlockCommentKind; } - static bool classof(const VerbatimBlockComment *) { return true; } - child_iterator child_begin() const { return reinterpret_cast<child_iterator>(Lines.begin()); } @@ -882,12 +881,12 @@ protected: public: VerbatimLineComment(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name, + unsigned CommandID, SourceLocation TextBegin, StringRef Text) : BlockCommandComment(VerbatimLineCommentKind, LocBegin, LocEnd, - Name), + CommandID), Text(Text), TextBegin(TextBegin) { } @@ -896,8 +895,6 @@ public: return C->getCommentKind() == VerbatimLineCommentKind; } - static bool classof(const VerbatimLineComment *) { return true; } - child_iterator child_begin() const { return NULL; } child_iterator child_end() const { return NULL; } @@ -913,23 +910,34 @@ public: /// Information about the declaration, useful to clients of FullComment. struct DeclInfo { - /// Declaration the comment is attached to. Should not be NULL. - const Decl *ThisDecl; - - /// Parameters that can be referenced by \\param if \c ThisDecl is something + /// Declaration the comment is actually attached to (in the source). + /// Should not be NULL. + const Decl *CommentDecl; + + /// CurrentDecl is the declaration with which the FullComment is associated. + /// + /// It can be different from \c CommentDecl. It happens when we we decide + /// that the comment originally attached to \c CommentDecl is fine for + /// \c CurrentDecl too (for example, for a redeclaration or an overrider of + /// \c CommentDecl). + /// + /// The information in the DeclInfo corresponds to CurrentDecl. + const Decl *CurrentDecl; + + /// Parameters that can be referenced by \\param if \c CommentDecl is something /// that we consider a "function". ArrayRef<const ParmVarDecl *> ParamVars; - /// Function result type if \c ThisDecl is something that we consider + /// Function result type if \c CommentDecl is something that we consider /// a "function". QualType ResultType; - /// Template parameters that can be referenced by \\tparam if \c ThisDecl is + /// Template parameters that can be referenced by \\tparam if \c CommentDecl is /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is /// true). const TemplateParameterList *TemplateParameters; - /// A simplified description of \c ThisDecl kind that should be good enough + /// A simplified description of \c CommentDecl kind that should be good enough /// for documentation rendering purposes. enum DeclKind { /// Everything else not explicitly mentioned below. @@ -942,7 +950,9 @@ struct DeclInfo { /// \li member function, /// \li member function template, /// \li member function template specialization, - /// \li ObjC method. + /// \li ObjC method, + /// \li a typedef for a function pointer, member function pointer, + /// ObjC block. FunctionKind, /// Something that we consider a "class": @@ -968,7 +978,7 @@ struct DeclInfo { EnumKind }; - /// What kind of template specialization \c ThisDecl is. + /// What kind of template specialization \c CommentDecl is. enum TemplateDeclKind { NotTemplate, Template, @@ -976,24 +986,24 @@ struct DeclInfo { TemplatePartialSpecialization }; - /// If false, only \c ThisDecl is valid. + /// If false, only \c CommentDecl is valid. unsigned IsFilled : 1; - /// Simplified kind of \c ThisDecl, see\c DeclKind enum. + /// Simplified kind of \c CommentDecl, see \c DeclKind enum. unsigned Kind : 3; - /// Is \c ThisDecl a template declaration. + /// Is \c CommentDecl a template declaration. unsigned TemplateKind : 2; - /// Is \c ThisDecl an ObjCMethodDecl. + /// Is \c CommentDecl an ObjCMethodDecl. unsigned IsObjCMethod : 1; - /// Is \c ThisDecl a non-static member function of C++ class or + /// Is \c CommentDecl a non-static member function of C++ class or /// instance method of ObjC class. /// Can be true only if \c IsFunctionDecl is true. unsigned IsInstanceMethod : 1; - /// Is \c ThisDecl a static member function of C++ class or + /// Is \c CommentDecl a static member function of C++ class or /// class method of ObjC class. /// Can be true only if \c IsFunctionDecl is true. unsigned IsClassMethod : 1; @@ -1012,7 +1022,6 @@ struct DeclInfo { /// A full comment attached to a declaration, contains block content. class FullComment : public Comment { llvm::ArrayRef<BlockContentComment *> Blocks; - DeclInfo *ThisDeclInfo; public: @@ -1031,27 +1040,31 @@ public: return C->getCommentKind() == FullCommentKind; } - static bool classof(const FullComment *) { return true; } - child_iterator child_begin() const { return reinterpret_cast<child_iterator>(Blocks.begin()); } child_iterator child_end() const { - return reinterpret_cast<child_iterator>(Blocks.end()); + return reinterpret_cast<child_iterator>(Blocks.end()); } const Decl *getDecl() const LLVM_READONLY { - return ThisDeclInfo->ThisDecl; + return ThisDeclInfo->CommentDecl; } - + const DeclInfo *getDeclInfo() const LLVM_READONLY { if (!ThisDeclInfo->IsFilled) ThisDeclInfo->fill(); return ThisDeclInfo; } + + DeclInfo *getThisDeclInfo() const LLVM_READONLY { + return ThisDeclInfo; + } + + llvm::ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; } + }; - } // end namespace comments } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentBriefParser.h b/contrib/llvm/tools/clang/include/clang/AST/CommentBriefParser.h index 003c337..5d50886 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentBriefParser.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentBriefParser.h @@ -44,8 +44,7 @@ class BriefParser { public: BriefParser(Lexer &L, const CommandTraits &Traits); - /// Return \\brief paragraph, if it exists; otherwise return the first - /// paragraph. + /// Return the best "brief description" we can find. std::string Parse(); }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h b/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h index 5f0269a..6d44c70 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h @@ -19,136 +19,132 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/ErrorHandling.h" namespace clang { namespace comments { -/// This class provides informaiton about commands that can be used -/// in comments. -class CommandTraits { -public: - CommandTraits() { } +/// \brief Information about a single command. +/// +/// When reordering, adding or removing members please update the corresponding +/// TableGen backend. +struct CommandInfo { + unsigned getID() const { + return ID; + } + + const char *Name; + + /// Name of the command that ends the verbatim block. + const char *EndCommandName; + + unsigned ID : 8; + + /// Number of word-like arguments for a given block command, except for + /// \\param and \\tparam commands -- these have special argument parsers. + unsigned NumArgs : 4; - /// \brief Check if a given command is a verbatim-like block command. + /// True if this command is a inline command (of any kind). + unsigned IsInlineCommand : 1; + + /// True if this command is a block command (of any kind). + unsigned IsBlockCommand : 1; + + /// True if this command is introducing a brief documentation + /// paragraph (\\brief or an alias). + unsigned IsBriefCommand : 1; + + /// True if this command is \\returns or an alias. + unsigned IsReturnsCommand : 1; + + /// True if this command is introducing documentation for a function + /// parameter (\\param or an alias). + unsigned IsParamCommand : 1; + + /// True if this command is introducing documentation for + /// a template parameter (\\tparam or an alias). + unsigned IsTParamCommand : 1; + + /// True if this command is \\deprecated or an alias. + unsigned IsDeprecatedCommand : 1; + + /// True if we don't want to warn about this command being passed an empty + /// paragraph. Meaningful only for block commands. + unsigned IsEmptyParagraphAllowed : 1; + + /// \brief True if this command is a verbatim-like block command. /// /// A verbatim-like block command eats every character (except line starting /// decorations) until matching end command is seen or comment end is hit. - /// - /// \param StartName name of the command that starts the verbatim block. - /// \param [out] EndName name of the command that ends the verbatim block. - /// - /// \returns true if a given command is a verbatim block command. - bool isVerbatimBlockCommand(StringRef StartName, StringRef &EndName) const; + unsigned IsVerbatimBlockCommand : 1; - /// \brief Register a new verbatim block command. - void addVerbatimBlockCommand(StringRef StartName, StringRef EndName); + /// \brief True if this command is an end command for a verbatim-like block. + unsigned IsVerbatimBlockEndCommand : 1; - /// \brief Check if a given command is a verbatim line command. + /// \brief True if this command is a verbatim line command. /// /// A verbatim-like line command eats everything until a newline is seen or /// comment end is hit. - bool isVerbatimLineCommand(StringRef Name) const; + unsigned IsVerbatimLineCommand : 1; - /// \brief Check if a given command is a command that contains a declaration - /// for the entity being documented. + /// \brief True if this command contains a declaration for the entity being + /// documented. /// /// For example: /// \code /// \fn void f(int a); /// \endcode - bool isDeclarationCommand(StringRef Name) const; + unsigned IsDeclarationCommand : 1; - /// \brief Register a new verbatim line command. - void addVerbatimLineCommand(StringRef Name); + /// \brief True if this command is unknown. This \c CommandInfo object was + /// created during parsing. + unsigned IsUnknownCommand : 1; +}; - /// \brief Check if a given command is a block command (of any kind). - bool isBlockCommand(StringRef Name) const; +/// This class provides information about commands that can be used +/// in comments. +class CommandTraits { +public: + CommandTraits(llvm::BumpPtrAllocator &Allocator); - /// \brief Check if a given command is introducing documentation for - /// a function parameter (\\param or an alias). - bool isParamCommand(StringRef Name) const; + /// \returns a CommandInfo object for a given command name or + /// NULL if no CommandInfo object exists for this command. + const CommandInfo *getCommandInfoOrNULL(StringRef Name) const; - /// \brief Check if a given command is introducing documentation for - /// a template parameter (\\tparam or an alias). - bool isTParamCommand(StringRef Name) const; + const CommandInfo *getCommandInfo(StringRef Name) const { + if (const CommandInfo *Info = getCommandInfoOrNULL(Name)) + return Info; + llvm_unreachable("the command should be known"); + } - /// \brief Check if a given command is introducing a brief documentation - /// paragraph (\\brief or an alias). - bool isBriefCommand(StringRef Name) const; + const CommandInfo *getCommandInfo(unsigned CommandID) const; - /// \brief Check if a given command is \\brief or an alias. - bool isReturnsCommand(StringRef Name) const; + const CommandInfo *registerUnknownCommand(StringRef CommandName); - /// \returns the number of word-like arguments for a given block command, - /// except for \\param and \\tparam commands -- these have special argument - /// parsers. - unsigned getBlockCommandNumArgs(StringRef Name) const; + /// \returns a CommandInfo object for a given command name or + /// NULL if \c Name is not a builtin command. + static const CommandInfo *getBuiltinCommandInfo(StringRef Name); - /// \brief Check if a given command is a inline command (of any kind). - bool isInlineCommand(StringRef Name) const; + /// \returns a CommandInfo object for a given command ID or + /// NULL if \c CommandID is not a builtin command. + static const CommandInfo *getBuiltinCommandInfo(unsigned CommandID); private: - struct VerbatimBlockCommand { - StringRef StartName; - StringRef EndName; - }; - - typedef SmallVector<VerbatimBlockCommand, 4> VerbatimBlockCommandVector; + CommandTraits(const CommandTraits &) LLVM_DELETED_FUNCTION; + void operator=(const CommandTraits &) LLVM_DELETED_FUNCTION; - /// Registered additional verbatim-like block commands. - VerbatimBlockCommandVector VerbatimBlockCommands; + const CommandInfo *getRegisteredCommandInfo(StringRef Name) const; + const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const; - struct VerbatimLineCommand { - StringRef Name; - }; + unsigned NextID; - typedef SmallVector<VerbatimLineCommand, 4> VerbatimLineCommandVector; + /// Allocator for CommandInfo objects. + llvm::BumpPtrAllocator &Allocator; - /// Registered verbatim-like line commands. - VerbatimLineCommandVector VerbatimLineCommands; + SmallVector<CommandInfo *, 4> RegisteredCommands; }; -inline bool CommandTraits::isBlockCommand(StringRef Name) const { - return isBriefCommand(Name) || isReturnsCommand(Name) || - isParamCommand(Name) || isTParamCommand(Name) || - llvm::StringSwitch<bool>(Name) - .Case("author", true) - .Case("authors", true) - .Case("pre", true) - .Case("post", true) - .Default(false); -} - -inline bool CommandTraits::isParamCommand(StringRef Name) const { - return Name == "param"; -} - -inline bool CommandTraits::isTParamCommand(StringRef Name) const { - return Name == "tparam" || // Doxygen - Name == "templatefield"; // HeaderDoc -} - -inline bool CommandTraits::isBriefCommand(StringRef Name) const { - return Name == "brief" || Name == "short"; -} - -inline bool CommandTraits::isReturnsCommand(StringRef Name) const { - return Name == "returns" || Name == "return" || Name == "result"; -} - -inline unsigned CommandTraits::getBlockCommandNumArgs(StringRef Name) const { - return 0; -} - -inline bool CommandTraits::isInlineCommand(StringRef Name) const { - return llvm::StringSwitch<bool>(Name) - .Case("b", true) - .Cases("c", "p", true) - .Cases("a", "e", "em", true) - .Default(false); -} - } // end namespace comments } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td b/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td new file mode 100644 index 0000000..3d8bad8 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td @@ -0,0 +1,156 @@ +class Command<string name> { + string Name = name; + string EndCommandName = ""; + + int NumArgs = 0; + + bit IsInlineCommand = 0; + + bit IsBlockCommand = 0; + bit IsBriefCommand = 0; + bit IsReturnsCommand = 0; + bit IsParamCommand = 0; + bit IsTParamCommand = 0; + bit IsDeprecatedCommand = 0; + + bit IsEmptyParagraphAllowed = 0; + + bit IsVerbatimBlockCommand = 0; + bit IsVerbatimBlockEndCommand = 0; + bit IsVerbatimLineCommand = 0; + bit IsDeclarationCommand = 0; +} + +class InlineCommand<string name> : Command<name> { + let IsInlineCommand = 1; +} + +class BlockCommand<string name> : Command<name> { + let IsBlockCommand = 1; +} + +class VerbatimBlockCommand<string name> : Command<name> { + let EndCommandName = name; + let IsVerbatimBlockCommand = 1; +} + +multiclass VerbatimBlockCommand<string name, string endCommandName> { + def Begin : Command<name> { + let EndCommandName = endCommandName; + let IsVerbatimBlockCommand = 1; + } + + def End : Command<endCommandName> { + let IsVerbatimBlockEndCommand = 1; + } +} + +class VerbatimLineCommand<string name> : Command<name> { + let IsVerbatimLineCommand = 1; +} + +class DeclarationVerbatimLineCommand<string name> : + VerbatimLineCommand<name> { + let IsDeclarationCommand = 1; +} + +def B : InlineCommand<"b">; +def C : InlineCommand<"c">; +def P : InlineCommand<"p">; +def A : InlineCommand<"a">; +def E : InlineCommand<"e">; +def Em : InlineCommand<"em">; + +def Brief : BlockCommand<"brief"> { let IsBriefCommand = 1; } +def Short : BlockCommand<"short"> { let IsBriefCommand = 1; } + +def Returns : BlockCommand<"returns"> { let IsReturnsCommand = 1; } +def Return : BlockCommand<"return"> { let IsReturnsCommand = 1; } +def Result : BlockCommand<"result"> { let IsReturnsCommand = 1; } + +def Param : BlockCommand<"param"> { let IsParamCommand = 1; } + +// Doxygen +def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; } + +// HeaderDoc +def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; } + +def Deprecated : BlockCommand<"deprecated"> { + let IsEmptyParagraphAllowed = 1; + let IsDeprecatedCommand = 1; +} + +def Author : BlockCommand<"author">; +def Authors : BlockCommand<"authors">; +def Bug : BlockCommand<"bug">; +def Copyright : BlockCommand<"copyright">; +def Date : BlockCommand<"date">; +def Details : BlockCommand<"details">; +def Invariant : BlockCommand<"invariant">; +def Note : BlockCommand<"note">; +def Post : BlockCommand<"post">; +def Pre : BlockCommand<"pre">; +def Remark : BlockCommand<"remark">; +def Remarks : BlockCommand<"remarks">; +def Sa : BlockCommand<"sa">; +def See : BlockCommand<"see">; +def Since : BlockCommand<"since">; +def Todo : BlockCommand<"todo">; +def Version : BlockCommand<"version">; +def Warning : BlockCommand<"warning">; + +defm Code : VerbatimBlockCommand<"code", "endcode">; +defm Verbatim : VerbatimBlockCommand<"verbatim", "endverbatim">; +defm Htmlonly : VerbatimBlockCommand<"htmlonly", "endhtmlonly">; +defm Latexonly : VerbatimBlockCommand<"latexonly", "endlatexonly">; +defm Xmlonly : VerbatimBlockCommand<"xmlonly", "endxmlonly">; +defm Manonly : VerbatimBlockCommand<"manonly", "endmanonly">; +defm Rtfonly : VerbatimBlockCommand<"rtfonly", "endrtfonly">; + +defm Dot : VerbatimBlockCommand<"dot", "enddot">; +defm Msc : VerbatimBlockCommand<"msc", "endmsc">; + +// These commands have special support in lexer. +def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula +defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula +defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment + +def Defgroup : VerbatimLineCommand<"defgroup">; +def Ingroup : VerbatimLineCommand<"ingroup">; +def Addtogroup : VerbatimLineCommand<"addtogroup">; +def Weakgroup : VerbatimLineCommand<"weakgroup">; +def Name : VerbatimLineCommand<"name">; + +def Section : VerbatimLineCommand<"section">; +def Subsection : VerbatimLineCommand<"subsection">; +def Subsubsection : VerbatimLineCommand<"subsubsection">; +def Paragraph : VerbatimLineCommand<"paragraph">; + +def Mainpage : VerbatimLineCommand<"mainpage">; +def Subpage : VerbatimLineCommand<"subpage">; +def Ref : VerbatimLineCommand<"ref">; + +// Doxygen commands. +def Fn : DeclarationVerbatimLineCommand<"fn">; +def Namespace : DeclarationVerbatimLineCommand<"namespace">; +def Overload : DeclarationVerbatimLineCommand<"overload">; +def Property : DeclarationVerbatimLineCommand<"property">; +def Typedef : DeclarationVerbatimLineCommand<"typedef">; +def Var : DeclarationVerbatimLineCommand<"var">; + +// HeaderDoc commands. +def Class : DeclarationVerbatimLineCommand<"class">; +def Interface : DeclarationVerbatimLineCommand<"interface">; +def Protocol : DeclarationVerbatimLineCommand<"protocol">; +def Category : DeclarationVerbatimLineCommand<"category">; +def Template : DeclarationVerbatimLineCommand<"template">; +def Function : DeclarationVerbatimLineCommand<"function">; +def Method : DeclarationVerbatimLineCommand<"method">; +def Callback : DeclarationVerbatimLineCommand<"callback">; +def Const : DeclarationVerbatimLineCommand<"const">; +def Constant : DeclarationVerbatimLineCommand<"constant">; +def Struct : DeclarationVerbatimLineCommand<"struct">; +def Union : DeclarationVerbatimLineCommand<"union">; +def Enum : DeclarationVerbatimLineCommand<"enum">; + diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentHTMLTags.td b/contrib/llvm/tools/clang/include/clang/AST/CommentHTMLTags.td new file mode 100644 index 0000000..f98e32d --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentHTMLTags.td @@ -0,0 +1,54 @@ +class Tag<string spelling> { + string Spelling = spelling; + bit EndTagOptional = 0; + bit EndTagForbidden = 0; +} + +def Em : Tag<"em">; +def Strong : Tag<"strong">; +def Tt : Tag<"tt">; +def I : Tag<"i">; +def B : Tag<"b">; +def Big : Tag<"big">; +def Small : Tag<"small">; +def Strike : Tag<"strike">; +def S : Tag<"s">; +def U : Tag<"u">; +def Font : Tag<"font">; +def A : Tag<"a">; +def Hr : Tag<"hr"> { let EndTagForbidden = 1; } +def Div : Tag<"div">; +def Span : Tag<"span">; +def H1 : Tag<"h1">; +def H2 : Tag<"h2">; +def H3 : Tag<"h3">; +def H4 : Tag<"h4">; +def H5 : Tag<"h5">; +def H6 : Tag<"h6">; +def Code : Tag<"code">; +def Blockquote : Tag<"blockquote">; +def Sub : Tag<"sub">; +def Sup : Tag<"sup">; +def Img : Tag<"img"> { let EndTagForbidden = 1; } +def P : Tag<"p"> { let EndTagOptional = 1; } +def Br : Tag<"br"> { let EndTagForbidden = 1; } +def Pre : Tag<"pre">; +def Ins : Tag<"ins">; +def Del : Tag<"del">; +def Ul : Tag<"ul">; +def Ol : Tag<"ol">; +def Li : Tag<"li"> { let EndTagOptional = 1; } +def Dl : Tag<"dl">; +def Dt : Tag<"dt"> { let EndTagOptional = 1; } +def Dd : Tag<"dd"> { let EndTagOptional = 1; } +def Table : Tag<"table">; +def Caption : Tag<"caption">; +def Thead : Tag<"thead"> { let EndTagOptional = 1; } +def Tfoot : Tag<"tfoot"> { let EndTagOptional = 1; } +def Tbody : Tag<"tbody"> { let EndTagOptional = 1; } +def Colgroup : Tag<"colgroup"> { let EndTagOptional = 1; } +def Col : Tag<"col"> { let EndTagForbidden = 1; } +def Tr : Tag<"tr"> { let EndTagOptional = 1; } +def Th : Tag<"th"> { let EndTagOptional = 1; } +def Td : Tag<"td"> { let EndTagOptional = 1; } + diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentLexer.h b/contrib/llvm/tools/clang/include/clang/AST/CommentLexer.h index 7a24b11..f263697 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentLexer.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentLexer.h @@ -26,6 +26,7 @@ namespace comments { class Lexer; class TextTokenRetokenizer; +struct CommandInfo; class CommandTraits; namespace tok { @@ -33,7 +34,8 @@ enum TokenKind { eof, newline, text, - command, + unknown_command, // Command that does not have an ID. + command, // Command with an ID. verbatim_block_begin, verbatim_block_line, verbatim_block_end, @@ -49,11 +51,6 @@ enum TokenKind { }; } // end namespace tok -class CommentOptions { -public: - bool Markdown; -}; - /// \brief Comment token. class Token { friend class Lexer; @@ -70,8 +67,14 @@ class Token { unsigned Length; /// Contains text value associated with a token. - const char *TextPtr1; - unsigned TextLen1; + const char *TextPtr; + + /// Integer value associated with a token. + /// + /// If the token is a konwn command, contains command ID and TextPtr is + /// unused (command spelling can be found with CommandTraits). Otherwise, + /// contains the length of the string that starts at TextPtr. + unsigned IntVal; public: SourceLocation getLocation() const LLVM_READONLY { return Loc; } @@ -94,113 +97,120 @@ public: StringRef getText() const LLVM_READONLY { assert(is(tok::text)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setText(StringRef Text) { assert(is(tok::text)); - TextPtr1 = Text.data(); - TextLen1 = Text.size(); + TextPtr = Text.data(); + IntVal = Text.size(); + } + + StringRef getUnknownCommandName() const LLVM_READONLY { + assert(is(tok::unknown_command)); + return StringRef(TextPtr, IntVal); + } + + void setUnknownCommandName(StringRef Name) { + assert(is(tok::unknown_command)); + TextPtr = Name.data(); + IntVal = Name.size(); } - StringRef getCommandName() const LLVM_READONLY { + unsigned getCommandID() const LLVM_READONLY { assert(is(tok::command)); - return StringRef(TextPtr1, TextLen1); + return IntVal; } - void setCommandName(StringRef Name) { + void setCommandID(unsigned ID) { assert(is(tok::command)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + IntVal = ID; } - StringRef getVerbatimBlockName() const LLVM_READONLY { + unsigned getVerbatimBlockID() const LLVM_READONLY { assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end)); - return StringRef(TextPtr1, TextLen1); + return IntVal; } - void setVerbatimBlockName(StringRef Name) { + void setVerbatimBlockID(unsigned ID) { assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + IntVal = ID; } StringRef getVerbatimBlockText() const LLVM_READONLY { assert(is(tok::verbatim_block_line)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setVerbatimBlockText(StringRef Text) { assert(is(tok::verbatim_block_line)); - TextPtr1 = Text.data(); - TextLen1 = Text.size(); + TextPtr = Text.data(); + IntVal = Text.size(); } - /// Returns the name of verbatim line command. - StringRef getVerbatimLineName() const LLVM_READONLY { + unsigned getVerbatimLineID() const LLVM_READONLY { assert(is(tok::verbatim_line_name)); - return StringRef(TextPtr1, TextLen1); + return IntVal; } - void setVerbatimLineName(StringRef Name) { + void setVerbatimLineID(unsigned ID) { assert(is(tok::verbatim_line_name)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + IntVal = ID; } StringRef getVerbatimLineText() const LLVM_READONLY { assert(is(tok::verbatim_line_text)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setVerbatimLineText(StringRef Text) { assert(is(tok::verbatim_line_text)); - TextPtr1 = Text.data(); - TextLen1 = Text.size(); + TextPtr = Text.data(); + IntVal = Text.size(); } StringRef getHTMLTagStartName() const LLVM_READONLY { assert(is(tok::html_start_tag)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setHTMLTagStartName(StringRef Name) { assert(is(tok::html_start_tag)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + TextPtr = Name.data(); + IntVal = Name.size(); } StringRef getHTMLIdent() const LLVM_READONLY { assert(is(tok::html_ident)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setHTMLIdent(StringRef Name) { assert(is(tok::html_ident)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + TextPtr = Name.data(); + IntVal = Name.size(); } StringRef getHTMLQuotedString() const LLVM_READONLY { assert(is(tok::html_quoted_string)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setHTMLQuotedString(StringRef Str) { assert(is(tok::html_quoted_string)); - TextPtr1 = Str.data(); - TextLen1 = Str.size(); + TextPtr = Str.data(); + IntVal = Str.size(); } StringRef getHTMLTagEndName() const LLVM_READONLY { assert(is(tok::html_end_tag)); - return StringRef(TextPtr1, TextLen1); + return StringRef(TextPtr, IntVal); } void setHTMLTagEndName(StringRef Name) { assert(is(tok::html_end_tag)); - TextPtr1 = Name.data(); - TextLen1 = Name.size(); + TextPtr = Name.data(); + IntVal = Name.size(); } void dump(const Lexer &L, const SourceManager &SM) const; @@ -209,8 +219,8 @@ public: /// \brief Comment lexer. class Lexer { private: - Lexer(const Lexer&); // DO NOT IMPLEMENT - void operator=(const Lexer&); // DO NOT IMPLEMENT + Lexer(const Lexer &) LLVM_DELETED_FUNCTION; + void operator=(const Lexer &) LLVM_DELETED_FUNCTION; /// Allocator for strings that are semantic values of tokens and have to be /// computed (for example, resolved decimal character references). @@ -221,7 +231,6 @@ private: const char *const BufferStart; const char *const BufferEnd; SourceLocation FileLoc; - CommentOptions CommOpts; const char *BufferPtr; @@ -286,8 +295,8 @@ private: Result.setKind(Kind); Result.setLength(TokLen); #ifndef NDEBUG - Result.TextPtr1 = "<UNSET>"; - Result.TextLen1 = 7; + Result.TextPtr = "<UNSET>"; + Result.IntVal = 7; #endif BufferPtr = TokEnd; } @@ -314,13 +323,14 @@ private: void setupAndLexVerbatimBlock(Token &T, const char *TextBegin, - char Marker, StringRef EndName); + char Marker, const CommandInfo *Info); void lexVerbatimBlockFirstLine(Token &T); void lexVerbatimBlockBody(Token &T); - void setupAndLexVerbatimLine(Token &T, const char *TextBegin); + void setupAndLexVerbatimLine(Token &T, const char *TextBegin, + const CommandInfo *Info); void lexVerbatimLineText(Token &T); @@ -336,7 +346,7 @@ private: public: Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits, - SourceLocation FileLoc, const CommentOptions &CommOpts, + SourceLocation FileLoc, const char *BufferStart, const char *BufferEnd); void lex(Token &T); diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h b/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h index 0390799..19e1d57 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h @@ -28,8 +28,8 @@ class CommandTraits; /// Doxygen comment parser. class Parser { - Parser(const Parser&); // DO NOT IMPLEMENT - void operator=(const Parser&); // DO NOT IMPLEMENT + Parser(const Parser &) LLVM_DELETED_FUNCTION; + void operator=(const Parser &) LLVM_DELETED_FUNCTION; friend class TextTokenRetokenizer; diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h b/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h index e1756ca..0340b3c 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h @@ -25,13 +25,14 @@ namespace clang { class Decl; class SourceMgr; +class Preprocessor; namespace comments { class CommandTraits; class Sema { - Sema(const Sema&); // DO NOT IMPLEMENT - void operator=(const Sema&); // DO NOT IMPLEMENT + Sema(const Sema &) LLVM_DELETED_FUNCTION; + void operator=(const Sema &) LLVM_DELETED_FUNCTION; /// Allocator for AST nodes. llvm::BumpPtrAllocator &Allocator; @@ -41,18 +42,13 @@ class Sema { DiagnosticsEngine &Diags; - const CommandTraits &Traits; + CommandTraits &Traits; + + const Preprocessor *PP; /// Information about the declaration this comment is attached to. DeclInfo *ThisDeclInfo; - /// Comment AST nodes that correspond to \c ParamVars for which we have - /// found a \\param command or NULL if no documentation was found so far. - /// - /// Has correct size and contains valid values if \c DeclInfo->IsFilled is - /// true. - llvm::SmallVector<ParamCommandComment *, 8> ParamVarDocs; - /// Comment AST nodes that correspond to parameter names in /// \c TemplateParameters. /// @@ -75,7 +71,8 @@ class Sema { public: Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, - DiagnosticsEngine &Diags, const CommandTraits &Traits); + DiagnosticsEngine &Diags, CommandTraits &Traits, + const Preprocessor *PP); void setDecl(const Decl *D); @@ -96,7 +93,7 @@ public: BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name); + unsigned CommandID); void actOnBlockCommandArgs(BlockCommandComment *Command, ArrayRef<BlockCommandComment::Argument> Args); @@ -106,7 +103,7 @@ public: ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name); + unsigned CommandID); void actOnParamCommandDirectionArg(ParamCommandComment *Command, SourceLocation ArgLocBegin, @@ -123,7 +120,7 @@ public: TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name); + unsigned CommandID); void actOnTParamCommandParamNameArg(TParamCommandComment *Command, SourceLocation ArgLocBegin, @@ -135,25 +132,29 @@ public: InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin, SourceLocation CommandLocEnd, - StringRef CommandName); + unsigned CommandID); InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin, SourceLocation CommandLocEnd, - StringRef CommandName, + unsigned CommandID, SourceLocation ArgLocBegin, SourceLocation ArgLocEnd, StringRef Arg); InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name); + StringRef CommandName); + + InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin, + SourceLocation LocEnd, + unsigned CommandID); TextComment *actOnText(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Text); VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc, - StringRef Name); + unsigned CommandID); VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc, StringRef Text); @@ -164,7 +165,7 @@ public: ArrayRef<VerbatimBlockLineComment *> Lines); VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin, - StringRef Name, + unsigned CommandID, SourceLocation TextBegin, StringRef Text); @@ -190,6 +191,12 @@ public: /// used only once per comment, e.g., \\brief and \\returns. void checkBlockCommandDuplicate(const BlockCommandComment *Command); + void checkDeprecatedCommand(const BlockCommandComment *Comment); + + /// Resolve parameter names to parameter indexes in function declaration. + /// Emit diagnostics about unknown parametrs. + void resolveParamCommandIndexes(const FullComment *FC); + bool isFunctionDecl(); bool isTemplateOrSpecialization(); @@ -218,9 +225,6 @@ public: InlineCommandComment::RenderKind getInlineCommandRenderKind(StringRef Name) const; - - bool isHTMLEndTagOptional(StringRef Name); - bool isHTMLEndTagForbidden(StringRef Name); }; } // end namespace comments diff --git a/contrib/llvm/tools/clang/include/clang/AST/Decl.h b/contrib/llvm/tools/clang/include/clang/AST/Decl.h index e9f25b3..087a585 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Decl.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Decl.h @@ -88,7 +88,6 @@ public: static TranslationUnitDecl *Create(ASTContext &C); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TranslationUnitDecl *D) { return true; } static bool classofKind(Kind K) { return K == TranslationUnit; } static DeclContext *castToDeclContext(const TranslationUnitDecl *D) { return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D)); @@ -214,16 +213,19 @@ public: bool isCXXInstanceMember() const; class LinkageInfo { - Linkage linkage_; - Visibility visibility_; - bool explicit_; + uint8_t linkage_ : 2; + uint8_t visibility_ : 2; + uint8_t explicit_ : 1; void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; } public: LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility), explicit_(false) {} LinkageInfo(Linkage L, Visibility V, bool E) - : linkage_(L), visibility_(V), explicit_(E) {} + : linkage_(L), visibility_(V), explicit_(E) { + assert(linkage() == L && visibility() == V && visibilityExplicit() == E && + "Enum truncated!"); + } static LinkageInfo external() { return LinkageInfo(); @@ -238,8 +240,8 @@ public: return LinkageInfo(NoLinkage, DefaultVisibility, false); } - Linkage linkage() const { return linkage_; } - Visibility visibility() const { return visibility_; } + Linkage linkage() const { return (Linkage)linkage_; } + Visibility visibility() const { return (Visibility)visibility_; } bool visibilityExplicit() const { return explicit_; } void setLinkage(Linkage L) { linkage_ = L; } @@ -337,7 +339,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const NamedDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; } }; @@ -383,7 +384,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const LabelDecl *D) { return true; } static bool classofKind(Kind K) { return K == Label; } }; @@ -509,7 +509,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const NamespaceDecl *D) { return true; } static bool classofKind(Kind K) { return K == Namespace; } static DeclContext *castToDeclContext(const NamespaceDecl *D) { return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D)); @@ -545,7 +544,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ValueDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; } }; @@ -578,8 +576,8 @@ struct QualifierInfo { private: // Copy constructor and copy assignment are disabled. - QualifierInfo(const QualifierInfo&); - QualifierInfo& operator=(const QualifierInfo&); + QualifierInfo(const QualifierInfo&) LLVM_DELETED_FUNCTION; + QualifierInfo& operator=(const QualifierInfo&) LLVM_DELETED_FUNCTION; }; /// \brief Represents a ValueDecl that came out of a declarator. @@ -666,7 +664,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const DeclaratorDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstDeclarator && K <= lastDeclarator; } @@ -712,7 +709,7 @@ public: typedef clang::StorageClass StorageClass; /// getStorageClassSpecifierString - Return the string used to - /// specify the storage class \arg SC. + /// specify the storage class \p SC. /// /// It is illegal to call this function with SC == None. static const char *getStorageClassSpecifierString(StorageClass SC); @@ -1208,7 +1205,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const VarDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; } }; @@ -1229,7 +1225,6 @@ public: } // Implement isa/cast/dyncast/etc. - static bool classof(const ImplicitParamDecl *D) { return true; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ImplicitParam; } }; @@ -1399,7 +1394,6 @@ public: // Implement isa/cast/dyncast/etc. 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: @@ -2070,7 +2064,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FunctionDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstFunction && K <= lastFunction; } @@ -2204,7 +2197,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FieldDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstField && K <= lastField; } friend class ASTDeclReader; @@ -2243,7 +2235,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const EnumConstantDecl *D) { return true; } static bool classofKind(Kind K) { return K == EnumConstant; } friend class StmtIteratorBase; @@ -2287,7 +2278,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const IndirectFieldDecl *D) { return true; } static bool classofKind(Kind K) { return K == IndirectField; } friend class ASTDeclReader; }; @@ -2334,7 +2324,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypeDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstType && K <= lastType; } }; @@ -2390,7 +2379,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypedefNameDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstTypedefName && K <= lastTypedefName; } @@ -2413,7 +2401,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypedefDecl *D) { return true; } static bool classofKind(Kind K) { return K == Typedef; } }; @@ -2434,7 +2421,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypeAliasDecl *D) { return true; } static bool classofKind(Kind K) { return K == TypeAlias; } }; @@ -2448,7 +2434,7 @@ public: private: // FIXME: This can be packed into the bitfields in Decl. /// TagDeclKind - The TagKind enum. - unsigned TagDeclKind : 2; + unsigned TagDeclKind : 3; /// IsCompleteDefinition - True if this is a definition ("struct foo /// {};"), false if it is a declaration ("struct foo;"). It is not @@ -2625,6 +2611,7 @@ public: void setTagKind(TagKind TK) { TagDeclKind = TK; } bool isStruct() const { return getTagKind() == TTK_Struct; } + bool isInterface() const { return getTagKind() == TTK_Interface; } bool isClass() const { return getTagKind() == TTK_Class; } bool isUnion() const { return getTagKind() == TTK_Union; } bool isEnum() const { return getTagKind() == TTK_Enum; } @@ -2665,7 +2652,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TagDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; } static DeclContext *castToDeclContext(const TagDecl *D) { @@ -2895,7 +2881,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const EnumDecl *D) { return true; } static bool classofKind(Kind K) { return K == Enum; } friend class ASTDeclReader; @@ -3026,11 +3011,15 @@ public: virtual void completeDefinition(); static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const RecordDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstRecord && K <= lastRecord; } + /// isMsStrust - Get whether or not this is an ms_struct which can + /// be turned on with an attribute, pragma, or -mms-bitfields + /// commandline option. + bool isMsStruct(const ASTContext &C) const; + private: /// \brief Deserialize just the fields. void LoadFieldsFromExternalStorage() const; @@ -3062,7 +3051,6 @@ public: void setAsmString(StringLiteral *Asm) { AsmString = Asm; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FileScopeAsmDecl *D) { return true; } static bool classofKind(Kind K) { return K == FileScopeAsm; } }; @@ -3208,7 +3196,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const BlockDecl *D) { return true; } static bool classofKind(Kind K) { return K == Block; } static DeclContext *castToDeclContext(const BlockDecl *D) { return static_cast<DeclContext *>(const_cast<BlockDecl*>(D)); @@ -3282,7 +3269,6 @@ public: virtual SourceRange getSourceRange() const LLVM_READONLY; static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ImportDecl *D) { return true; } static bool classofKind(Kind K) { return K == Import; } }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h index 0f59609..50e2027 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h @@ -430,16 +430,10 @@ public: void dropAttr() { if (!HasAttrs) return; - AttrVec &Attrs = getAttrs(); - for (unsigned i = 0, e = Attrs.size(); i != e; /* in loop */) { - if (isa<T>(Attrs[i])) { - Attrs.erase(Attrs.begin() + i); - --e; - } - else - ++i; - } - if (Attrs.empty()) + AttrVec &Vec = getAttrs(); + Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa<T, Attr*>), Vec.end()); + + if (Vec.empty()) HasAttrs = false; } @@ -844,8 +838,6 @@ public: IdentifierNamespace |= IDNS_NonMemberOperator; } - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *) { return true; } static bool classofKind(Kind K) { return true; } static DeclContext *castToDeclContext(const Decl *); static Decl *castFromDeclContext(const DeclContext *); @@ -1479,6 +1471,13 @@ public: inline ddiag_iterator ddiag_end() const; // Low-level accessors + + /// \brief Mark the lookup table as needing to be built. This should be + /// used only if setHasExternalLexicalStorage() has been called. + void setMustBuildLookupTable() { + assert(ExternalLexicalStorage && "Requires external lexical storage"); + LookupPtr.setInt(true); + } /// \brief Retrieve the internal representation of the lookup structure. /// This may omit some names if we are lazily building the structure. @@ -1516,10 +1515,6 @@ public: static bool classof(const Decl *D); static bool classof(const DeclContext *D) { return true; } -#define DECL(NAME, BASE) -#define DECL_CONTEXT(NAME) \ - static bool classof(const NAME##Decl *D) { return true; } -#include "clang/AST/DeclNodes.inc" LLVM_ATTRIBUTE_USED void dumpDeclContext() const; diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h index 2d95f03..9cb56e2 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h @@ -145,7 +145,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const AccessSpecDecl *D) { return true; } static bool classofKind(Kind K) { return K == AccessSpec; } }; @@ -563,9 +562,10 @@ class CXXRecordDecl : public RecordDecl { struct LambdaDefinitionData : public DefinitionData { typedef LambdaExpr::Capture Capture; - LambdaDefinitionData(CXXRecordDecl *D, bool Dependent) + LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent) : DefinitionData(D), Dependent(Dependent), NumCaptures(0), - NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0) + NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0), + MethodTyInfo(Info) { IsLambda = true; } @@ -598,7 +598,10 @@ class CXXRecordDecl : public RecordDecl { /// \brief The list of captures, both explicit and implicit, for this /// lambda. - Capture *Captures; + Capture *Captures; + + /// \brief The type of the call method. + TypeSourceInfo *MethodTyInfo; }; struct DefinitionData &data() { @@ -705,7 +708,8 @@ public: IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0, bool DelayTypeCreation = false); static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC, - SourceLocation Loc, bool DependentLambda); + TypeSourceInfo *Info, SourceLocation Loc, + bool DependentLambda); static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); bool isDynamicClass() const { @@ -1303,7 +1307,7 @@ public: /// \brief Function type used by forallBases() as a callback. /// - /// \param Base the definition of the base class + /// \param BaseDefinition the definition of the base class /// /// \returns true if this base matched the search criteria typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition, @@ -1500,15 +1504,15 @@ public: bool isDependentLambda() const { return isLambda() && getLambdaData().Dependent; } - + + TypeSourceInfo *getLambdaTypeInfo() const { + return getLambdaData().MethodTyInfo; + } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstCXXRecord && K <= lastCXXRecord; } - static bool classof(const CXXRecordDecl *D) { return true; } - static bool classof(const ClassTemplateSpecializationDecl *D) { - return true; - } friend class ASTDeclReader; friend class ASTDeclWriter; @@ -1549,14 +1553,16 @@ public: bool isStatic() const { return getStorageClass() == SC_Static; } bool isInstance() const { return !isStatic(); } - bool isConst() { return getType()->castAs<FunctionType>()->isConst(); } - bool isVolatile() { return getType()->castAs<FunctionType>()->isVolatile(); } + bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); } + bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); } bool isVirtual() const { CXXMethodDecl *CD = cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl()); - if (CD->isVirtualAsWritten()) + // Methods declared in interfaces are automatically (pure) virtual. + if (CD->isVirtualAsWritten() || + (CD->getParent()->isInterface() && CD->isUserProvided())) return true; return (CD->begin_overridden_methods() != CD->end_overridden_methods()); @@ -1661,7 +1667,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const CXXMethodDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstCXXMethod && K <= lastCXXMethod; } @@ -2141,7 +2146,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const CXXConstructorDecl *D) { return true; } static bool classofKind(Kind K) { return K == CXXConstructor; } friend class ASTDeclReader; @@ -2213,7 +2217,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const CXXDestructorDecl *D) { return true; } static bool classofKind(Kind K) { return K == CXXDestructor; } friend class ASTDeclReader; @@ -2280,7 +2283,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const CXXConversionDecl *D) { return true; } static bool classofKind(Kind K) { return K == CXXConversion; } friend class ASTDeclReader; @@ -2350,7 +2352,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const LinkageSpecDecl *D) { return true; } static bool classofKind(Kind K) { return K == LinkageSpec; } static DeclContext *castToDeclContext(const LinkageSpecDecl *D) { return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D)); @@ -2454,7 +2455,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UsingDirectiveDecl *D) { return true; } static bool classofKind(Kind K) { return K == UsingDirective; } // Friend for getUsingDirectiveName. @@ -2548,7 +2548,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const NamespaceAliasDecl *D) { return true; } static bool classofKind(Kind K) { return K == NamespaceAlias; } }; @@ -2619,7 +2618,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UsingShadowDecl *D) { return true; } static bool classofKind(Kind K) { return K == Decl::UsingShadow; } friend class ASTDeclReader; @@ -2751,7 +2749,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UsingDecl *D) { return true; } static bool classofKind(Kind K) { return K == Using; } friend class ASTDeclReader; @@ -2825,7 +2822,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UnresolvedUsingValueDecl *D) { return true; } static bool classofKind(Kind K) { return K == UnresolvedUsingValue; } friend class ASTDeclReader; @@ -2891,7 +2887,6 @@ public: CreateDeserialized(ASTContext &C, unsigned ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; } static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; } }; @@ -2931,7 +2926,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(StaticAssertDecl *D) { return true; } static bool classofKind(Kind K) { return K == StaticAssert; } friend class ASTDeclReader; diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h index 9a64f08..37e4586 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_AST_DECLFRIEND_H #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" #include "llvm/Support/Compiler.h" namespace clang { @@ -104,9 +105,15 @@ public: /// Retrieves the source range for the friend declaration. SourceRange getSourceRange() const LLVM_READONLY { - /* FIXME: consider the case of templates wrt start of range. */ - if (NamedDecl *ND = getFriendDecl()) + if (NamedDecl *ND = getFriendDecl()) { + if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND)) + return FTD->getSourceRange(); + if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) { + if (DD->getOuterLocStart() != DD->getInnerLocStart()) + return DD->getSourceRange(); + } return SourceRange(getFriendLoc(), ND->getLocEnd()); + } else if (TypeSourceInfo *TInfo = getFriendType()) return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc()); else @@ -123,7 +130,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FriendDecl *D) { return true; } static bool classofKind(Kind K) { return K == Decl::Friend; } friend class ASTDeclReader; diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h index 6c39f2c..8b27dd8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h @@ -33,8 +33,8 @@ class ObjCPropertyImplDecl; class CXXCtorInitializer; class ObjCListBase { - void operator=(const ObjCListBase &); // DO NOT IMPLEMENT - ObjCListBase(const ObjCListBase&); // DO NOT IMPLEMENT + ObjCListBase(const ObjCListBase &) LLVM_DELETED_FUNCTION; + void operator=(const ObjCListBase &) LLVM_DELETED_FUNCTION; protected: /// List is an array of pointers to objects that are not owned by this object. void **List; @@ -123,8 +123,8 @@ private: unsigned IsInstance : 1; unsigned IsVariadic : 1; - // Synthesized declaration method for a property setter/getter - unsigned IsSynthesized : 1; + /// True if this method is the getter or setter for an explicit property. + unsigned IsPropertyAccessor : 1; // Method has a definition. unsigned IsDefined : 1; @@ -174,8 +174,7 @@ private: SourceLocation DeclEndLoc; // the location of the ';' or '{'. // The following are only used for method definitions, null otherwise. - // FIXME: space savings opportunity, consider a sub-class. - Stmt *Body; + LazyDeclStmtPtr Body; /// SelfDecl - Decl for the implicit self parameter. This is lazily /// constructed by createImplicitParams. @@ -227,7 +226,7 @@ private: DeclContext *contextDecl, bool isInstance = true, bool isVariadic = false, - bool isSynthesized = false, + bool isPropertyAccessor = false, bool isImplicitlyDeclared = false, bool isDefined = false, ImplementationControl impControl = None, @@ -235,14 +234,14 @@ private: : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), IsInstance(isInstance), IsVariadic(isVariadic), - IsSynthesized(isSynthesized), + IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), RelatedResultType(HasRelatedResultType), SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), MethodDeclType(T), ResultTInfo(ResultTInfo), ParamsAndSelLocs(0), NumParams(0), - DeclEndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) { + DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) { setImplicit(isImplicitlyDeclared); } @@ -261,7 +260,7 @@ public: DeclContext *contextDecl, bool isInstance = true, bool isVariadic = false, - bool isSynthesized = false, + bool isPropertyAccessor = false, bool isImplicitlyDeclared = false, bool isDefined = false, ImplementationControl impControl = None, @@ -363,7 +362,7 @@ public: } /// \brief Sets the method's parameters and selector source locations. - /// If the method is implicit (not coming from source) \arg SelLocs is + /// If the method is implicit (not coming from source) \p SelLocs is /// ignored. void setMethodParams(ASTContext &C, ArrayRef<ParmVarDecl*> Params, @@ -403,8 +402,8 @@ public: bool isClassMethod() const { return !IsInstance; } - bool isSynthesized() const { return IsSynthesized; } - void setSynthesized(bool isSynth) { IsSynthesized = isSynth; } + bool isPropertyAccessor() const { return IsPropertyAccessor; } + void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; } bool isDefined() const { return IsDefined; } void setDefined(bool isDefined) { IsDefined = isDefined; } @@ -418,7 +417,25 @@ public: /// method in the interface or its categories. bool isOverriding() const { return IsOverriding; } void setOverriding(bool isOverriding) { IsOverriding = isOverriding; } - + + /// \brief Return overridden methods for the given \p Method. + /// + /// An ObjC method is considered to override any method in the class's + /// base classes (and base's categories), its protocols, or its categories' + /// protocols, that has + /// the same selector and is of the same kind (class or instance). + /// A method in an implementation is not considered as overriding the same + /// method in the interface or its categories. + void getOverriddenMethods( + SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const; + + /// \brief Returns the property associated with this method's selector. + /// + /// Note that even if this particular method is not marked as a property + /// accessor, it is still possible for it to match a property declared in a + /// superclass. Pass \c false if you only want to check the current class. + const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const; + // Related to protocols declared in \@protocol void setDeclImplementation(ImplementationControl ic) { DeclImplementation = ic; @@ -427,10 +444,15 @@ public: return ImplementationControl(DeclImplementation); } - virtual Stmt *getBody() const { - return (Stmt*) Body; - } - CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; } + /// \brief Determine whether this method has a body. + virtual bool hasBody() const { return Body; } + + /// \brief Retrieve the body of this method, if it has one. + virtual Stmt *getBody() const; + + void setLazyBody(uint64_t Offset) { Body = Offset; } + + CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); } void setBody(Stmt *B) { Body = B; } /// \brief Returns whether this specific method is a definition. @@ -438,7 +460,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCMethodDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCMethod; } static DeclContext *castToDeclContext(const ObjCMethodDecl *D) { return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D)); @@ -520,6 +541,13 @@ public: ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; + typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap; + + /// This routine collects list of properties to be implemented in the class. + /// This includes, class's and its conforming protocols' properties. + /// Note, the superclass's properties are not included in the list. + virtual void collectPropertiesToImplement(PropertyMap &PM) const {} + SourceLocation getAtStartLoc() const { return AtStart; } void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } @@ -537,7 +565,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCContainerDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstObjCContainer && K <= lastObjCContainer; @@ -880,6 +907,8 @@ public: ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; + virtual void collectPropertiesToImplement(PropertyMap &PM) const; + /// isSuperClassOf - Return true if this class is the specified class or is a /// super class of the specified interface class. bool isSuperClassOf(const ObjCInterfaceDecl *I) const { @@ -992,7 +1021,6 @@ public: void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCInterfaceDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCInterface; } friend class ASTReader; @@ -1065,7 +1093,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCIvarDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCIvar; } private: /// NextIvar - Next Ivar in the list of ivars declared in class; class's @@ -1098,7 +1125,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCAtDefsFieldDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCAtDefsField; } }; @@ -1277,8 +1303,9 @@ public: return getFirstDeclaration(); } + virtual void collectPropertiesToImplement(PropertyMap &PM) const; + static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCProtocolDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCProtocol; } friend class ASTReader; @@ -1402,7 +1429,6 @@ public: SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } 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; @@ -1455,7 +1481,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCImplDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstObjCImpl && K <= lastObjCImpl; } @@ -1532,7 +1557,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCCategoryImplDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCCategoryImpl;} friend class ASTDeclReader; @@ -1568,8 +1592,12 @@ class ObjCImplementationDecl : public ObjCImplDecl { CXXCtorInitializer **IvarInitializers; unsigned NumIvarInitializers; - /// true if class has a .cxx_[construct,destruct] method. - bool HasCXXStructors : 1; + /// Do the ivars of this class require initialization other than + /// zero-initialization? + bool HasNonZeroConstructors : 1; + + /// Do the ivars of this class require non-trivial destruction? + bool HasDestructors : 1; ObjCImplementationDecl(DeclContext *DC, ObjCInterfaceDecl *classInterface, @@ -1581,7 +1609,7 @@ class ObjCImplementationDecl : public ObjCImplDecl { SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc), IvarInitializers(0), NumIvarInitializers(0), - HasCXXStructors(false) {} + HasNonZeroConstructors(false), HasDestructors(false) {} public: static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, ObjCInterfaceDecl *classInterface, @@ -1625,8 +1653,15 @@ public: CXXCtorInitializer ** initializers, unsigned numInitializers); - bool hasCXXStructors() const { return HasCXXStructors; } - void setHasCXXStructors(bool val) { HasCXXStructors = val; } + /// Do any of the ivars of this class (not counting its base classes) + /// require construction other than zero-initialization? + bool hasNonZeroConstructors() const { return HasNonZeroConstructors; } + void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; } + + /// Do any of the ivars of this class (not counting its base classes) + /// require non-trivial destruction? + bool hasDestructors() const { return HasDestructors; } + void setHasDestructors(bool val) { HasDestructors = val; } /// getIdentifier - Get the identifier that names the class /// interface associated with this implementation. @@ -1676,7 +1711,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCImplementationDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCImplementation; } friend class ASTDeclReader; @@ -1708,7 +1742,6 @@ public: void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCCompatibleAliasDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; } }; @@ -1882,13 +1915,15 @@ public: virtual SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(AtLoc, getLocation()); } + + /// Get the default name of the synthesized ivar. + IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const; /// Lookup a property by name in the specified DeclContext. static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, IdentifierInfo *propertyID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCPropertyDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCProperty; } }; @@ -1999,7 +2034,6 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ObjCPropertyImplDecl *D) { return true; } static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; } friend class ASTDeclReader; diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h index 7affc7e..8620116 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h @@ -50,7 +50,11 @@ class TemplateParameterList { /// The number of template parameters in this template /// parameter list. - unsigned NumParams; + unsigned NumParams : 31; + + /// Whether this template parameter list contains an unexpanded parameter + /// pack. + unsigned ContainsUnexpandedParameterPack : 1; protected: TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, @@ -104,6 +108,12 @@ public: /// the second template parameter list will have depth 1, etc. unsigned getDepth() const; + /// \brief Determine whether this template parameter list contains an + /// unexpanded parameter pack. + bool containsUnexpandedParameterPack() const { + return ContainsUnexpandedParameterPack; + } + SourceLocation getTemplateLoc() const { return TemplateLoc; } SourceLocation getLAngleLoc() const { return LAngleLoc; } SourceLocation getRAngleLoc() const { return RAngleLoc; } @@ -139,8 +149,8 @@ class TemplateArgumentList { /// argument list. unsigned NumArguments; - TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL - void operator=(const TemplateArgumentList &Other); // DO NOT IMPL + TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; + void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, bool Owned) @@ -233,12 +243,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TemplateDecl *D) { return true; } - static bool classof(const RedeclarableTemplateDecl *D) { return true; } - static bool classof(const FunctionTemplateDecl *D) { return true; } - static bool classof(const ClassTemplateDecl *D) { return true; } - static bool classof(const TemplateTemplateParmDecl *D) { return true; } - static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstTemplate && K <= lastTemplate; } @@ -678,10 +682,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const RedeclarableTemplateDecl *D) { return true; } - static bool classof(const FunctionTemplateDecl *D) { return true; } - static bool classof(const ClassTemplateDecl *D) { return true; } - static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate; } @@ -827,7 +827,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const FunctionTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K == FunctionTemplate; } friend class ASTDeclReader; @@ -969,7 +968,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TemplateTypeParmDecl *D) { return true; } static bool classofKind(Kind K) { return K == TemplateTypeParm; } }; @@ -1090,8 +1088,17 @@ public: /// \endcode bool isParameterPack() const { return ParameterPack; } + /// \brief Whether this parameter pack is a pack expansion. + /// + /// A non-type template parameter pack is a pack expansion if its type + /// contains an unexpanded parameter pack. In this case, we will have + /// built a PackExpansionType wrapping the type. + bool isPackExpansion() const { + return ParameterPack && getType()->getAs<PackExpansionType>(); + } + /// \brief Whether this parameter is a non-type template parameter pack - /// that has different types at different positions. + /// that has a known list of different types at different positions. /// /// A parameter pack is an expanded parameter pack when the original /// parameter pack's type was itself a pack expansion, and that expansion @@ -1141,7 +1148,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const NonTypeTemplateParmDecl *D) { return true; } static bool classofKind(Kind K) { return K == NonTypeTemplateParm; } }; @@ -1165,23 +1171,47 @@ class TemplateTemplateParmDecl : public TemplateDecl, /// \brief Whether this parameter is a parameter pack. bool ParameterPack; + /// \brief Whether this template template parameter is an "expanded" + /// parameter pack, meaning that it is a pack expansion and we + /// already know the set of template parameters that expansion expands to. + bool ExpandedParameterPack; + + /// \brief The number of parameters in an expanded parameter pack. + unsigned NumExpandedParams; + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params) : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), TemplateParmPosition(D, P), DefaultArgument(), - DefaultArgumentWasInherited(false), ParameterPack(ParameterPack) + DefaultArgumentWasInherited(false), ParameterPack(ParameterPack), + ExpandedParameterPack(false), NumExpandedParams(0) { } + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, + unsigned D, unsigned P, + IdentifierInfo *Id, TemplateParameterList *Params, + unsigned NumExpansions, + TemplateParameterList * const *Expansions); + public: static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params); + static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, + SourceLocation L, unsigned D, + unsigned P, + IdentifierInfo *Id, + TemplateParameterList *Params, + llvm::ArrayRef<TemplateParameterList*> Expansions); - static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, + static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, + unsigned ID, + unsigned NumExpansions); using TemplateParmPosition::getDepth; using TemplateParmPosition::getPosition; @@ -1195,6 +1225,49 @@ public: /// \endcode bool isParameterPack() const { return ParameterPack; } + /// \brief Whether this parameter pack is a pack expansion. + /// + /// A template template parameter pack is a pack expansion if its template + /// parameter list contains an unexpanded parameter pack. + bool isPackExpansion() const { + return ParameterPack && + getTemplateParameters()->containsUnexpandedParameterPack(); + } + + /// \brief Whether this parameter is a template template parameter pack that + /// has a known list of different template parameter lists at different + /// positions. + /// + /// A parameter pack is an expanded parameter pack when the original parameter + /// pack's template parameter list was itself a pack expansion, and that + /// expansion has already been expanded. For exampe, given: + /// + /// \code + /// template<typename...Types> struct Outer { + /// template<template<Types> class...Templates> struct Inner; + /// }; + /// \endcode + /// + /// The parameter pack \c Templates is a pack expansion, which expands the + /// pack \c Types. When \c Types is supplied with template arguments by + /// instantiating \c Outer, the instantiation of \c Templates is an expanded + /// parameter pack. + bool isExpandedParameterPack() const { return ExpandedParameterPack; } + + /// \brief Retrieves the number of expansion template parameters in + /// an expanded parameter pack. + unsigned getNumExpansionTemplateParameters() const { + assert(ExpandedParameterPack && "Not an expansion parameter pack"); + return NumExpandedParams; + } + + /// \brief Retrieve a particular expansion type within an expanded parameter + /// pack. + TemplateParameterList *getExpansionTemplateParameters(unsigned I) const { + assert(I < NumExpandedParams && "Out-of-range expansion type index"); + return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I]; + } + /// \brief Determine whether this template parameter has a default /// argument. bool hasDefaultArgument() const { @@ -1238,7 +1311,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TemplateTemplateParmDecl *D) { return true; } static bool classofKind(Kind K) { return K == TemplateTemplateParm; } friend class ASTDeclReader; @@ -1505,14 +1577,6 @@ public: K <= lastClassTemplateSpecialization; } - static bool classof(const ClassTemplateSpecializationDecl *) { - return true; - } - - static bool classof(const ClassTemplatePartialSpecializationDecl *) { - return true; - } - friend class ASTDeclReader; friend class ASTDeclWriter; }; @@ -1681,10 +1745,6 @@ public: return K == ClassTemplatePartialSpecialization; } - static bool classof(const ClassTemplatePartialSpecializationDecl *) { - return true; - } - friend class ASTDeclReader; friend class ASTDeclWriter; }; @@ -1886,7 +1946,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const ClassTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K == ClassTemplate; } friend class ASTDeclReader; @@ -1984,7 +2043,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::FriendTemplate; } - static bool classof(const FriendTemplateDecl *D) { return true; } friend class ASTDeclReader; }; @@ -2059,7 +2117,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K == TypeAliasTemplate; } friend class ASTDeclReader; @@ -2123,9 +2180,6 @@ public: static bool classofKind(Kind K) { return K == Decl::ClassScopeFunctionSpecialization; } - static bool classof(const ClassScopeFunctionSpecializationDecl *D) { - return true; - } friend class ASTDeclReader; friend class ASTDeclWriter; diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h index 6146525..d991c73 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h @@ -334,8 +334,8 @@ class DeclarationNameTable { CXXOperatorIdName *CXXOperatorNames; // Operator names void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName* - DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE - DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE + DeclarationNameTable(const DeclarationNameTable&) LLVM_DELETED_FUNCTION; + void operator=(const DeclarationNameTable&) LLVM_DELETED_FUNCTION; public: DeclarationNameTable(const ASTContext &C); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Expr.h b/contrib/llvm/tools/clang/include/clang/AST/Expr.h index 89c003c..dc83654 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Expr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Expr.h @@ -34,6 +34,7 @@ namespace clang { class ASTContext; class APValue; + class CastExpr; class Decl; class IdentifierInfo; class ParmVarDecl; @@ -42,6 +43,7 @@ namespace clang { class BlockDecl; class CXXBaseSpecifier; class CXXOperatorCallExpr; + class MaterializeTemporaryExpr; class CXXMemberCallExpr; class ObjCPropertyRefExpr; class OpaqueValueExpr; @@ -49,6 +51,48 @@ namespace clang { /// \brief A simple array of base specifiers. typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; +/// \brief An adjustment to be made to the temporary created when emitting a +/// reference binding, which accesses a particular subobject of that temporary. +struct SubobjectAdjustment { + enum { + DerivedToBaseAdjustment, + FieldAdjustment, + MemberPointerAdjustment + } Kind; + + union { + struct { + const CastExpr *BasePath; + const CXXRecordDecl *DerivedClass; + } DerivedToBase; + + FieldDecl *Field; + + struct { + const MemberPointerType *MPT; + Expr *RHS; + } Ptr; + }; + + SubobjectAdjustment(const CastExpr *BasePath, + const CXXRecordDecl *DerivedClass) + : Kind(DerivedToBaseAdjustment) { + DerivedToBase.BasePath = BasePath; + DerivedToBase.DerivedClass = DerivedClass; + } + + SubobjectAdjustment(FieldDecl *Field) + : Kind(FieldAdjustment) { + this->Field = Field; + } + + SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS) + : Kind(MemberPointerAdjustment) { + this->Ptr.MPT = MPT; + this->Ptr.RHS = RHS; + } +}; + /// 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 /// is required. @@ -220,15 +264,6 @@ public: /// Reasons why an expression might not be an l-value. LValueClassification ClassifyLValue(ASTContext &Ctx) const; - /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, - /// does not have an incomplete type, does not have a const-qualified type, - /// and if it is a structure or union, does not have any member (including, - /// recursively, any member or element of all contained aggregates or unions) - /// with a const-qualified type. - /// - /// \param Loc [in,out] - A source location which *may* be filled - /// in with the location of the expression making this a - /// non-modifiable lvalue, if specified. enum isModifiableLvalueResult { MLV_Valid, MLV_NotObjectType, @@ -247,6 +282,15 @@ public: MLV_ClassTemporary, MLV_ArrayTemporary }; + /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, + /// does not have an incomplete type, does not have a const-qualified type, + /// and if it is a structure or union, does not have any member (including, + /// recursively, any member or element of all contained aggregates or unions) + /// with a const-qualified type. + /// + /// \param Loc [in,out] - A source location which *may* be filled + /// in with the location of the expression making this a + /// non-modifiable lvalue, if specified. isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = 0) const; @@ -392,6 +436,9 @@ public: /// property, find the underlying property reference expression. const ObjCPropertyRefExpr *getObjCProperty() const; + /// \brief Check if this expression is the ObjC 'self' implicit parameter. + bool isObjCSelfExpr() const; + /// \brief Returns whether this expression refers to a vector element. bool refersToVectorElement() const; @@ -692,11 +739,22 @@ public: /// behavior if the object isn't dynamically of the derived type. const CXXRecordDecl *getBestDynamicClassType() const; + /// Walk outwards from an expression we want to bind a reference to and + /// find the expression whose lifetime needs to be extended. Record + /// the adjustments needed along the path. + const Expr * + skipRValueSubobjectAdjustments( + SmallVectorImpl<SubobjectAdjustment> &Adjustments) const; + + /// Skip irrelevant expressions to find what should be materialize for + /// binding with a reference. + const Expr * + findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const; + static bool classof(const Stmt *T) { return T->getStmtClass() >= firstExprConstant && T->getStmtClass() <= lastExprConstant; } - static bool classof(const Expr *) { return true; } }; @@ -762,7 +820,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == OpaqueValueExprClass; } - static bool classof(const OpaqueValueExpr *) { return true; } }; /// \brief A reference to a declared variable, function, enum, etc. @@ -1059,7 +1116,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DeclRefExprClass; } - static bool classof(const DeclRefExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1109,7 +1165,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == PredefinedExprClass; } - static bool classof(const PredefinedExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1132,8 +1187,8 @@ class APNumericStorage { bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; } - APNumericStorage(const APNumericStorage&); // do not implement - APNumericStorage& operator=(const APNumericStorage&); // do not implement + APNumericStorage(const APNumericStorage &) LLVM_DELETED_FUNCTION; + void operator=(const APNumericStorage &) LLVM_DELETED_FUNCTION; protected: APNumericStorage() : VAL(0), BitWidth(0) { } @@ -1196,7 +1251,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == IntegerLiteralClass; } - static bool classof(const IntegerLiteral *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1243,7 +1297,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CharacterLiteralClass; } - static bool classof(const CharacterLiteral *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1286,7 +1339,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == FloatingLiteralClass; } - static bool classof(const FloatingLiteral *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1317,7 +1369,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ImaginaryLiteralClass; } - static bool classof(const ImaginaryLiteral *) { return true; } // Iterators child_range children() { return child_range(&Val, &Val+1); } @@ -1479,7 +1530,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == StringLiteralClass; } - static bool classof(const StringLiteral *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1520,7 +1570,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ParenExprClass; } - static bool classof(const ParenExpr *) { return true; } // Iterators child_range children() { return child_range(&Val, &Val+1); } @@ -1610,7 +1659,7 @@ public: /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// corresponds to, e.g. "sizeof" or "[pre]++" - static const char *getOpcodeStr(Opcode Op); + static StringRef getOpcodeStr(Opcode Op); /// \brief Retrieve the unary opcode that corresponds to the given /// overloaded operator. @@ -1631,7 +1680,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnaryOperatorClass; } - static bool classof(const UnaryOperator *) { return true; } // Iterators child_range children() { return child_range(&Val, &Val+1); } @@ -1757,8 +1805,7 @@ private: OffsetOfExpr(ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, - OffsetOfNode* compsPtr, unsigned numComps, - Expr** exprsPtr, unsigned numExprs, + ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs, SourceLocation RParenLoc); explicit OffsetOfExpr(unsigned numComps, unsigned numExprs) @@ -1769,9 +1816,8 @@ public: static OffsetOfExpr *Create(ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, - OffsetOfNode* compsPtr, unsigned numComps, - Expr** exprsPtr, unsigned numExprs, - SourceLocation RParenLoc); + ArrayRef<OffsetOfNode> comps, + ArrayRef<Expr*> exprs, SourceLocation RParenLoc); static OffsetOfExpr *CreateEmpty(ASTContext &C, unsigned NumComps, unsigned NumExprs); @@ -1832,8 +1878,6 @@ public: return T->getStmtClass() == OffsetOfExprClass; } - static bool classof(const OffsetOfExpr *) { return true; } - // Iterators child_range children() { Stmt **begin = @@ -1937,7 +1981,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnaryExprOrTypeTraitExprClass; } - static bool classof(const UnaryExprOrTypeTraitExpr *) { return true; } // Iterators child_range children(); @@ -2017,7 +2060,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ArraySubscriptExprClass; } - static bool classof(const ArraySubscriptExpr *) { return true; } // Iterators child_range children() { @@ -2041,7 +2083,7 @@ class CallExpr : public Expr { protected: // These versions of the constructor are for derived classes. CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, - Expr **args, unsigned numargs, QualType t, ExprValueKind VK, + ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation rparenloc); CallExpr(ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty); @@ -2061,7 +2103,7 @@ protected: unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; } public: - CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t, + CallExpr(ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation rparenloc); /// \brief Build an empty call expression. @@ -2153,7 +2195,6 @@ public: return T->getStmtClass() >= firstCallExprConstant && T->getStmtClass() <= lastCallExprConstant; } - static bool classof(const CallExpr *) { return true; } // Iterators child_range children() { @@ -2440,7 +2481,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == MemberExprClass; } - static bool classof(const MemberExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base+1); } @@ -2506,7 +2546,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CompoundLiteralExprClass; } - static bool classof(const CompoundLiteralExpr *) { return true; } // Iterators child_range children() { return child_range(&Init, &Init+1); } @@ -2597,7 +2636,6 @@ public: return T->getStmtClass() >= firstCastExprConstant && T->getStmtClass() <= lastCastExprConstant; } - static bool classof(const CastExpr *) { return true; } // Iterators child_range children() { return child_range(&Op, &Op+1); } @@ -2661,7 +2699,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitCastExprClass; } - static bool classof(const ImplicitCastExpr *) { return true; } }; inline Expr *Expr::IgnoreImpCasts() { @@ -2716,7 +2753,6 @@ public: return T->getStmtClass() >= firstExplicitCastExprConstant && T->getStmtClass() <= lastExplicitCastExprConstant; } - static bool classof(const ExplicitCastExpr *) { return true; } }; /// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style @@ -2757,7 +2793,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CStyleCastExprClass; } - static bool classof(const CStyleCastExpr *) { return true; } }; /// \brief A builtin binary operation expression such as "x + y" or "x <= y". @@ -2784,6 +2819,12 @@ public: private: unsigned Opc : 6; + + // Records the FP_CONTRACT pragma status at the point that this binary + // operator was parsed. This bit is only meaningful for operations on + // floating point types. For all other types it should default to + // false. + unsigned FPContractable : 1; SourceLocation OpLoc; enum { LHS, RHS, END_EXPR }; @@ -2792,7 +2833,7 @@ public: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc) + SourceLocation opLoc, bool fpContractable) : Expr(BinaryOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), @@ -2800,7 +2841,7 @@ public: rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), - Opc(opc), OpLoc(opLoc) { + Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; assert(!isCompoundAssignmentOp() && @@ -2829,9 +2870,9 @@ public: /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// corresponds to, e.g. "<<=". - static const char *getOpcodeStr(Opcode Op); + static StringRef getOpcodeStr(Opcode Op); - const char *getOpcodeStr() const { return getOpcodeStr(getOpcode()); } + StringRef getOpcodeStr() const { return getOpcodeStr(getOpcode()); } /// \brief Retrieve the binary opcode that corresponds to the given /// overloaded operator. @@ -2894,17 +2935,24 @@ public: return S->getStmtClass() >= firstBinaryOperatorConstant && S->getStmtClass() <= lastBinaryOperatorConstant; } - static bool classof(const BinaryOperator *) { return true; } // Iterators child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + // Set the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + void setFPContractable(bool FPC) { FPContractable = FPC; } + + // Get the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + bool isFPContractable() const { return FPContractable; } + protected: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc, bool dead) + SourceLocation opLoc, bool fpContractable, bool dead2) : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), @@ -2912,7 +2960,7 @@ protected: rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), - Opc(opc), OpLoc(opLoc) { + Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; } @@ -2934,8 +2982,9 @@ public: CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType, ExprValueKind VK, ExprObjectKind OK, QualType CompLHSType, QualType CompResultType, - SourceLocation OpLoc) - : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, true), + SourceLocation OpLoc, bool fpContractable) + : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable, + true), ComputationLHSType(CompLHSType), ComputationResultType(CompResultType) { assert(isCompoundAssignmentOp() && @@ -2955,7 +3004,6 @@ public: QualType getComputationResultType() const { return ComputationResultType; } void setComputationResultType(QualType T) { ComputationResultType = T; } - static bool classof(const CompoundAssignOperator *) { return true; } static bool classof(const Stmt *S) { return S->getStmtClass() == CompoundAssignOperatorClass; } @@ -3001,7 +3049,6 @@ public: return T->getStmtClass() == ConditionalOperatorClass || T->getStmtClass() == BinaryConditionalOperatorClass; } - static bool classof(const AbstractConditionalOperator *) { return true; } }; /// ConditionalOperator - The ?: ternary operator. The GNU "missing @@ -3060,7 +3107,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ConditionalOperatorClass; } - static bool classof(const ConditionalOperator *) { return true; } // Iterators child_range children() { @@ -3142,7 +3188,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == BinaryConditionalOperatorClass; } - static bool classof(const BinaryConditionalOperator *) { return true; } // Iterators child_range children() { @@ -3198,7 +3243,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == AddrLabelExprClass; } - static bool classof(const AddrLabelExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -3242,7 +3286,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == StmtExprClass; } - static bool classof(const StmtExpr *) { return true; } // Iterators child_range children() { return child_range(&SubStmt, &SubStmt+1); } @@ -3266,9 +3309,8 @@ class ShuffleVectorExpr : public Expr { unsigned NumExprs; public: - ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, - QualType Type, SourceLocation BLoc, - SourceLocation RP); + ShuffleVectorExpr(ASTContext &C, ArrayRef<Expr*> args, QualType Type, + SourceLocation BLoc, SourceLocation RP); /// \brief Build an empty vector-shuffle expression. explicit ShuffleVectorExpr(EmptyShell Empty) @@ -3286,7 +3328,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ShuffleVectorExprClass; } - static bool classof(const ShuffleVectorExpr *) { return true; } /// getNumSubExprs - Return the size of the SubExprs array. This includes the /// constant expression, the actual arguments passed in, and the function @@ -3308,7 +3349,7 @@ public: void setExprs(ASTContext &C, Expr ** Exprs, unsigned NumExprs); - unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) { + unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) const { assert((N < NumExprs - 2) && "Shuffle idx out of range!"); return getExpr(N+2)->EvaluateKnownConstInt(Ctx).getZExtValue(); } @@ -3381,7 +3422,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ChooseExprClass; } - static bool classof(const ChooseExpr *) { return true; } // Iterators child_range children() { @@ -3418,7 +3458,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == GNUNullExprClass; } - static bool classof(const GNUNullExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -3464,7 +3503,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == VAArgExprClass; } - static bool classof(const VAArgExpr *) { return true; } // Iterators child_range children() { return child_range(&Val, &Val+1); } @@ -3501,21 +3539,32 @@ public: /// initializer lists may still have fewer initializers than there are /// elements to initialize within the object. /// +/// After semantic analysis has completed, given an initializer list, +/// method isSemanticForm() returns true if and only if this is the +/// semantic form of the initializer list (note: the same AST node +/// may at the same time be the syntactic form). /// Given the semantic form of the initializer list, one can retrieve -/// the original syntactic form of that initializer list (if it -/// exists) using getSyntacticForm(). Since many initializer lists -/// have the same syntactic and semantic forms, getSyntacticForm() may -/// return NULL, indicating that the current initializer list also -/// serves as its syntactic form. +/// the syntactic form of that initializer list (when different) +/// using method getSyntacticForm(); the method returns null if applied +/// to a initializer list which is already in syntactic form. +/// Similarly, given the syntactic form (i.e., an initializer list such +/// that isSemanticForm() returns false), one can retrieve the semantic +/// form using method getSemanticForm(). +/// Since many initializer lists have the same syntactic and semantic forms, +/// getSyntacticForm() may return NULL, indicating that the current +/// semantic initializer list also serves as its syntactic form. class InitListExpr : public Expr { // FIXME: Eliminate this vector in favor of ASTContext allocation typedef ASTVector<Stmt *> InitExprsTy; InitExprsTy InitExprs; SourceLocation LBraceLoc, RBraceLoc; - /// Contains the initializer list that describes the syntactic form - /// written in the source code. - InitListExpr *SyntacticForm; + /// The alternative form of the initializer list (if it exists). + /// The int part of the pair stores whether this initalizer list is + /// in semantic form. If not null, the pointer points to: + /// - the syntactic form, if this is in semantic form; + /// - the semantic form, if this is in syntactic form. + llvm::PointerIntPair<InitListExpr *, 1, bool> AltForm; /// \brief Either: /// If this initializer list initializes an array with more elements than @@ -3528,8 +3577,7 @@ class InitListExpr : public Expr { public: InitListExpr(ASTContext &C, SourceLocation lbraceloc, - Expr **initexprs, unsigned numinits, - SourceLocation rbraceloc); + ArrayRef<Expr*> initExprs, SourceLocation rbraceloc); /// \brief Build an empty initializer list. explicit InitListExpr(ASTContext &C, EmptyShell Empty) @@ -3621,12 +3669,20 @@ public: SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; } - /// @brief Retrieve the initializer list that describes the - /// syntactic form of the initializer. - /// - /// - InitListExpr *getSyntacticForm() const { return SyntacticForm; } - void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; } + bool isSemanticForm() const { return AltForm.getInt(); } + InitListExpr *getSemanticForm() const { + return isSemanticForm() ? 0 : AltForm.getPointer(); + } + InitListExpr *getSyntacticForm() const { + return isSemanticForm() ? AltForm.getPointer() : 0; + } + + void setSyntacticForm(InitListExpr *Init) { + AltForm.setPointer(Init); + AltForm.setInt(true); + Init->AltForm.setPointer(this); + Init->AltForm.setInt(false); + } bool hadArrayRangeDesignator() const { return InitListExprBits.HadArrayRangeDesignator != 0; @@ -3647,7 +3703,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == InitListExprClass; } - static bool classof(const InitListExpr *) { return true; } // Iterators child_range children() { @@ -3723,8 +3778,7 @@ private: DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumDesignators, const Designator *Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, - Expr **IndexExprs, unsigned NumIndexExprs, - Expr *Init); + ArrayRef<Expr*> IndexExprs, Expr *Init); explicit DesignatedInitExpr(unsigned NumSubExprs) : Expr(DesignatedInitExprClass, EmptyShell()), @@ -3885,7 +3939,7 @@ public: static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators, unsigned NumDesignators, - Expr **IndexExprs, unsigned NumIndexExprs, + ArrayRef<Expr*> IndexExprs, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr *Init); @@ -3985,7 +4039,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DesignatedInitExprClass; } - static bool classof(const DesignatedInitExpr *) { return true; } // Iterators child_range children() { @@ -4015,7 +4068,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitValueInitExprClass; } - static bool classof(const ImplicitValueInitExpr *) { return true; } SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); @@ -4032,8 +4084,8 @@ class ParenListExpr : public Expr { SourceLocation LParenLoc, RParenLoc; public: - ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, - unsigned numexprs, SourceLocation rparenloc); + ParenListExpr(ASTContext& C, SourceLocation lparenloc, ArrayRef<Expr*> exprs, + SourceLocation rparenloc); /// \brief Build an empty paren list. explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } @@ -4061,7 +4113,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ParenListExprClass; } - static bool classof(const ParenListExpr *) { return true; } // Iterators child_range children() { @@ -4109,18 +4160,18 @@ class GenericSelectionExpr : public Expr { public: GenericSelectionExpr(ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, - TypeSourceInfo **AssocTypes, Expr **AssocExprs, - unsigned NumAssocs, SourceLocation DefaultLoc, - SourceLocation RParenLoc, + ArrayRef<TypeSourceInfo*> AssocTypes, + ArrayRef<Expr*> AssocExprs, + SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex); /// This constructor is used in the result-dependent case. GenericSelectionExpr(ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, - TypeSourceInfo **AssocTypes, Expr **AssocExprs, - unsigned NumAssocs, SourceLocation DefaultLoc, - SourceLocation RParenLoc, + ArrayRef<TypeSourceInfo*> AssocTypes, + ArrayRef<Expr*> AssocExprs, + SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack); explicit GenericSelectionExpr(EmptyShell Empty) @@ -4176,7 +4227,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == GenericSelectionExprClass; } - static bool classof(const GenericSelectionExpr *) { return true; } child_range children() { return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs); @@ -4247,7 +4297,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ExtVectorElementExprClass; } - static bool classof(const ExtVectorElementExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base+1); } @@ -4289,7 +4338,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == BlockExprClass; } - static bool classof(const BlockExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -4336,7 +4384,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == AsTypeExprClass; } - static bool classof(const AsTypeExpr *) { return true; } // Iterators child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } @@ -4473,7 +4520,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == PseudoObjectExprClass; } - static bool classof(const PseudoObjectExpr *) { return true; } }; /// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, @@ -4501,7 +4547,7 @@ private: friend class ASTStmtReader; public: - AtomicExpr(SourceLocation BLoc, Expr **args, unsigned nexpr, QualType t, + AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t, AtomicOp op, SourceLocation RP); /// \brief Determine the number of arguments the specified atomic builtin @@ -4563,7 +4609,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == AtomicExprClass; } - static bool classof(const AtomicExpr *) { return true; } // Iterators child_range children() { diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h index ecfa9e2..9c759db 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h @@ -53,14 +53,19 @@ class CXXOperatorCallExpr : public CallExpr { OverloadedOperatorKind Operator; SourceRange Range; + // Record the FP_CONTRACT state that applies to this operator call. Only + // meaningful for floating point types. For other types this value can be + // set to false. + unsigned FPContractable : 1; + SourceRange getSourceRangeImpl() const LLVM_READONLY; public: CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn, - Expr **args, unsigned numargs, QualType t, - ExprValueKind VK, SourceLocation operatorloc) - : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, numargs, t, VK, + ArrayRef<Expr*> args, QualType t, ExprValueKind VK, + SourceLocation operatorloc, bool fpContractable) + : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK, operatorloc), - Operator(Op) { + Operator(Op), FPContractable(fpContractable) { Range = getSourceRangeImpl(); } explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) : @@ -83,7 +88,14 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXOperatorCallExprClass; } - static bool classof(const CXXOperatorCallExpr *) { return true; } + + // Set the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + void setFPContractable(bool FPC) { FPContractable = FPC; } + + // Get the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + bool isFPContractable() const { return FPContractable; } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -99,9 +111,9 @@ public: /// the object argument). class CXXMemberCallExpr : public CallExpr { public: - CXXMemberCallExpr(ASTContext &C, Expr *fn, Expr **args, unsigned numargs, + CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, numargs, t, VK, RP) {} + : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {} CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CXXMemberCallExprClass, Empty) { } @@ -124,7 +136,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXMemberCallExprClass; } - static bool classof(const CXXMemberCallExpr *) { return true; } }; /// CUDAKernelCallExpr - Represents a call to a CUDA kernel function. @@ -134,10 +145,9 @@ private: public: CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config, - Expr **args, unsigned numargs, QualType t, - ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, numargs, t, VK, - RP) { + ArrayRef<Expr*> args, QualType t, ExprValueKind VK, + SourceLocation RP) + : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) { setConfig(Config); } @@ -153,7 +163,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CUDAKernelCallExprClass; } - static bool classof(const CUDAKernelCallExpr *) { return true; } }; /// CXXNamedCastExpr - Abstract class common to all of the C++ "named" @@ -205,7 +214,6 @@ public: return false; } } - static bool classof(const CXXNamedCastExpr *) { return true; } }; /// CXXStaticCastExpr - A C++ @c static_cast expression @@ -235,7 +243,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXStaticCastExprClass; } - static bool classof(const CXXStaticCastExpr *) { return true; } }; /// CXXDynamicCastExpr - A C++ @c dynamic_cast expression @@ -269,7 +276,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDynamicCastExprClass; } - static bool classof(const CXXDynamicCastExpr *) { return true; } }; /// CXXReinterpretCastExpr - A C++ @c reinterpret_cast expression (C++ @@ -301,7 +307,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXReinterpretCastExprClass; } - static bool classof(const CXXReinterpretCastExpr *) { return true; } }; /// CXXConstCastExpr - A C++ @c const_cast expression (C++ [expr.const.cast]), @@ -329,7 +334,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstCastExprClass; } - static bool classof(const CXXConstCastExpr *) { return true; } }; /// UserDefinedLiteral - A call to a literal operator (C++11 [over.literal]) @@ -346,11 +350,11 @@ class UserDefinedLiteral : public CallExpr { SourceLocation UDSuffixLoc; public: - UserDefinedLiteral(ASTContext &C, Expr *Fn, Expr **Args, unsigned NumArgs, + UserDefinedLiteral(ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args, QualType T, ExprValueKind VK, SourceLocation LitEndLoc, SourceLocation SuffixLoc) - : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, NumArgs, T, VK, - LitEndLoc), UDSuffixLoc(SuffixLoc) {} + : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc), + UDSuffixLoc(SuffixLoc) {} explicit UserDefinedLiteral(ASTContext &C, EmptyShell Empty) : CallExpr(C, UserDefinedLiteralClass, Empty) {} @@ -398,7 +402,6 @@ public: static bool classof(const Stmt *S) { return S->getStmtClass() == UserDefinedLiteralClass; } - static bool classof(const UserDefinedLiteral *) { return true; } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -429,7 +432,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXBoolLiteralExprClass; } - static bool classof(const CXXBoolLiteralExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -455,7 +457,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXNullPtrLiteralExprClass; } - static bool classof(const CXXNullPtrLiteralExpr *) { return true; } child_range children() { return child_range(); } }; @@ -536,7 +537,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTypeidExprClass; } - static bool classof(const CXXTypeidExpr *) { return true; } // Iterators child_range children() { @@ -611,7 +611,9 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXUuidofExprClass; } - static bool classof(const CXXUuidofExpr *) { return true; } + + /// Grabs __declspec(uuid()) off a type, or returns 0 if there is none. + static UuidAttr *GetUuidAttrOfType(QualType QT); // Iterators child_range children() { @@ -659,7 +661,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXThisExprClass; } - static bool classof(const CXXThisExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -710,7 +711,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXThrowExprClass; } - static bool classof(const CXXThrowExpr *) { return true; } // Iterators child_range children() { @@ -798,7 +798,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDefaultArgExprClass; } - static bool classof(const CXXDefaultArgExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -875,7 +874,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXBindTemporaryExprClass; } - static bool classof(const CXXBindTemporaryExpr *) { return true; } // Iterators child_range children() { return child_range(&SubExpr, &SubExpr + 1); } @@ -908,7 +906,7 @@ protected: CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, SourceLocation Loc, CXXConstructorDecl *d, bool elidable, - Expr **args, unsigned numargs, + ArrayRef<Expr *> Args, bool HadMultipleCandidates, bool ListInitialization, bool ZeroInitialization, @@ -934,7 +932,7 @@ public: static CXXConstructExpr *Create(ASTContext &C, QualType T, SourceLocation Loc, CXXConstructorDecl *D, bool Elidable, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, bool HadMultipleCandidates, bool ListInitialization, bool ZeroInitialization, @@ -1011,7 +1009,6 @@ public: return T->getStmtClass() == CXXConstructExprClass || T->getStmtClass() == CXXTemporaryObjectExprClass; } - static bool classof(const CXXConstructExpr *) { return true; } // Iterators child_range children() { @@ -1066,7 +1063,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXFunctionalCastExprClass; } - static bool classof(const CXXFunctionalCastExpr *) { return true; } }; /// @brief Represents a C++ functional cast expression that builds a @@ -1090,7 +1086,7 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr { public: CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons, TypeSourceInfo *Type, - Expr **Args,unsigned NumArgs, + ArrayRef<Expr *> Args, SourceRange parenRange, bool HadMultipleCandidates, bool ZeroInitialization = false); @@ -1104,7 +1100,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTemporaryObjectExprClass; } - static bool classof(const CXXTemporaryObjectExpr *) { return true; } friend class ASTStmtReader; }; @@ -1281,8 +1276,11 @@ private: /// \brief Retrieve the complete set of array-index variables. VarDecl **getArrayIndexVars() const { + unsigned ArrayIndexSize = + llvm::RoundUpToAlignment(sizeof(unsigned) * (NumCaptures + 1), + llvm::alignOf<VarDecl*>()); return reinterpret_cast<VarDecl **>( - getArrayIndexStarts() + NumCaptures + 1); + reinterpret_cast<char*>(getArrayIndexStarts()) + ArrayIndexSize); } public: @@ -1394,7 +1392,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == LambdaExprClass; } - static bool classof(const LambdaExpr *) { return true; } SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(IntroducerRange.getBegin(), ClosingBrace); @@ -1442,7 +1439,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXScalarValueInitExprClass; } - static bool classof(const CXXScalarValueInitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1467,8 +1463,8 @@ class CXXNewExpr : public Expr { /// the source range covering the parenthesized type-id. SourceRange TypeIdParens; - /// \brief Location of the first token. - SourceLocation StartLoc; + /// \brief Range of the entire new expression. + SourceRange Range; /// \brief Source-range of a paren-delimited initializer. SourceRange DirectInitRange; @@ -1498,11 +1494,11 @@ public: CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize, - Expr **placementArgs, unsigned numPlaceArgs, + ArrayRef<Expr*> placementArgs, SourceRange typeIdParens, Expr *arraySize, InitializationStyle initializationStyle, Expr *initializer, QualType ty, TypeSourceInfo *AllocatedTypeInfo, - SourceLocation startLoc, SourceRange directInitRange); + SourceRange Range, SourceRange directInitRange); explicit CXXNewExpr(EmptyShell Shell) : Expr(CXXNewExprClass, Shell), SubExprs(0) { } @@ -1580,7 +1576,7 @@ public: } /// \brief Returns the CXXConstructExpr from this new-expression, or NULL. - const CXXConstructExpr* getConstructExpr() { + const CXXConstructExpr* getConstructExpr() const { return dyn_cast_or_null<CXXConstructExpr>(getInitializer()); } @@ -1617,19 +1613,18 @@ public: return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); } - SourceLocation getStartLoc() const { return StartLoc; } - SourceLocation getEndLoc() const; + SourceLocation getStartLoc() const { return Range.getBegin(); } + SourceLocation getEndLoc() const { return Range.getEnd(); } SourceRange getDirectInitRange() const { return DirectInitRange; } SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getStartLoc(), getEndLoc()); + return Range; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXNewExprClass; } - static bool classof(const CXXNewExpr *) { return true; } // Iterators child_range children() { @@ -1700,7 +1695,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDeleteExprClass; } - static bool classof(const CXXDeleteExpr *) { return true; } // Iterators child_range children() { return child_range(&Argument, &Argument+1); } @@ -1889,7 +1883,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXPseudoDestructorExprClass; } - static bool classof(const CXXPseudoDestructorExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base + 1); } @@ -1945,7 +1938,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnaryTypeTraitExprClass; } - static bool classof(const UnaryTypeTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2017,7 +2009,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == BinaryTypeTraitExprClass; } - static bool classof(const BinaryTypeTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2111,7 +2102,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == TypeTraitExprClass; } - static bool classof(const TypeTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2186,7 +2176,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ArrayTypeTraitExprClass; } - static bool classof(const ArrayTypeTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2245,7 +2234,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ExpressionTraitExprClass; } - static bool classof(const ExpressionTraitExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -2432,7 +2420,6 @@ public: return T->getStmtClass() == UnresolvedLookupExprClass || T->getStmtClass() == UnresolvedMemberExprClass; } - static bool classof(const OverloadExpr *) { return true; } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -2454,10 +2441,6 @@ class UnresolvedLookupExpr : public OverloadExpr { /// call. bool RequiresADL; - /// True if namespace ::std should be considered an associated namespace - /// for the purposes of argument-dependent lookup. See C++0x [stmt.ranged]p1. - bool StdIsAssociatedNamespace; - /// True if these lookup results are overloaded. This is pretty /// trivially rederivable if we urgently need to kill this field. bool Overloaded; @@ -2476,19 +2459,16 @@ class UnresolvedLookupExpr : public OverloadExpr { const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, const TemplateArgumentListInfo *TemplateArgs, - UnresolvedSetIterator Begin, UnresolvedSetIterator End, - bool StdIsAssociatedNamespace) + UnresolvedSetIterator Begin, UnresolvedSetIterator End) : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc, NameInfo, TemplateArgs, Begin, End, false, false, false), RequiresADL(RequiresADL), - StdIsAssociatedNamespace(StdIsAssociatedNamespace), Overloaded(Overloaded), NamingClass(NamingClass) {} UnresolvedLookupExpr(EmptyShell Empty) : OverloadExpr(UnresolvedLookupExprClass, Empty), - RequiresADL(false), StdIsAssociatedNamespace(false), Overloaded(false), - NamingClass(0) + RequiresADL(false), Overloaded(false), NamingClass(0) {} friend class ASTStmtReader; @@ -2500,14 +2480,10 @@ public: const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, - UnresolvedSetIterator End, - bool StdIsAssociatedNamespace = false) { - assert((ADL || !StdIsAssociatedNamespace) && - "std considered associated namespace when not performing ADL"); + UnresolvedSetIterator End) { return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, SourceLocation(), NameInfo, - ADL, Overloaded, 0, Begin, End, - StdIsAssociatedNamespace); + ADL, Overloaded, 0, Begin, End); } static UnresolvedLookupExpr *Create(ASTContext &C, @@ -2528,10 +2504,6 @@ public: /// argument-dependent lookup. bool requiresADL() const { return RequiresADL; } - /// True if namespace \::std should be artificially added to the set of - /// associated namespaces for argument-dependent lookup purposes. - bool isStdAssociatedNamespace() const { return StdIsAssociatedNamespace; } - /// True if this lookup is overloaded. bool isOverloaded() const { return Overloaded; } @@ -2554,7 +2526,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnresolvedLookupExprClass; } - static bool classof(const UnresolvedLookupExpr *) { return true; } }; /// \brief A qualified reference to a name whose declaration cannot @@ -2705,7 +2676,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DependentScopeDeclRefExprClass; } - static bool classof(const DependentScopeDeclRefExpr *) { return true; } child_range children() { return child_range(); } @@ -2778,7 +2748,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ExprWithCleanupsClass; } - static bool classof(const ExprWithCleanups *) { return true; } // Iterators child_range children() { return child_range(&SubExpr, &SubExpr + 1); } @@ -2820,8 +2789,7 @@ class CXXUnresolvedConstructExpr : public Expr { CXXUnresolvedConstructExpr(TypeSourceInfo *Type, SourceLocation LParenLoc, - Expr **Args, - unsigned NumArgs, + ArrayRef<Expr*> Args, SourceLocation RParenLoc); CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs) @@ -2833,8 +2801,7 @@ public: static CXXUnresolvedConstructExpr *Create(ASTContext &C, TypeSourceInfo *Type, SourceLocation LParenLoc, - Expr **Args, - unsigned NumArgs, + ArrayRef<Expr*> Args, SourceLocation RParenLoc); static CXXUnresolvedConstructExpr *CreateEmpty(ASTContext &C, @@ -2893,7 +2860,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXUnresolvedConstructExprClass; } - static bool classof(const CXXUnresolvedConstructExpr *) { return true; } // Iterators child_range children() { @@ -3142,7 +3108,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDependentScopeMemberExprClass; } - static bool classof(const CXXDependentScopeMemberExpr *) { return true; } // Iterators child_range children() { @@ -3276,7 +3241,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == UnresolvedMemberExprClass; } - static bool classof(const UnresolvedMemberExpr *) { return true; } // Iterators child_range children() { @@ -3320,7 +3284,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXNoexceptExprClass; } - static bool classof(const CXXNoexceptExpr *) { return true; } // Iterators child_range children() { return child_range(&Operand, &Operand + 1); } @@ -3397,7 +3360,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == PackExpansionExprClass; } - static bool classof(const PackExpansionExpr *) { return true; } // Iterators child_range children() { @@ -3503,7 +3465,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == SizeOfPackExprClass; } - static bool classof(const SizeOfPackExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -3548,9 +3509,6 @@ public: static bool classof(const Stmt *s) { return s->getStmtClass() == SubstNonTypeTemplateParmExprClass; } - static bool classof(const SubstNonTypeTemplateParmExpr *) { - return true; - } // Iterators child_range children() { return child_range(&Replacement, &Replacement+1); } @@ -3561,7 +3519,7 @@ public: /// /// When a pack expansion in the source code contains multiple parameter packs /// and those parameter packs correspond to different levels of template -/// parameter lists, this node node is used to represent a non-type template +/// parameter lists, this node is used to represent a non-type template /// parameter pack from an outer level, which has already had its argument pack /// substituted but that still lives within a pack expansion that itself /// could not be instantiated. When actually performing a substitution into @@ -3608,14 +3566,77 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass; } - static bool classof(const SubstNonTypeTemplateParmPackExpr *) { - return true; - } // Iterators child_range children() { return child_range(); } }; +/// \brief Represents a reference to a function parameter pack that has been +/// substituted but not yet expanded. +/// +/// When a pack expansion contains multiple parameter packs at different levels, +/// this node is used to represent a function parameter pack at an outer level +/// which we have already substituted to refer to expanded parameters, but where +/// the containing pack expansion cannot yet be expanded. +/// +/// \code +/// template<typename...Ts> struct S { +/// template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...)); +/// }; +/// template struct S<int, int>; +/// \endcode +class FunctionParmPackExpr : public Expr { + /// \brief The function parameter pack which was referenced. + ParmVarDecl *ParamPack; + + /// \brief The location of the function parameter pack reference. + SourceLocation NameLoc; + + /// \brief The number of expansions of this pack. + unsigned NumParameters; + + FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack, + SourceLocation NameLoc, unsigned NumParams, + Decl * const *Params); + + friend class ASTReader; + friend class ASTStmtReader; + +public: + static FunctionParmPackExpr *Create(ASTContext &Context, QualType T, + ParmVarDecl *ParamPack, + SourceLocation NameLoc, + llvm::ArrayRef<Decl*> Params); + static FunctionParmPackExpr *CreateEmpty(ASTContext &Context, + unsigned NumParams); + + /// \brief Get the parameter pack which this expression refers to. + ParmVarDecl *getParameterPack() const { return ParamPack; } + + /// \brief Get the location of the parameter pack. + SourceLocation getParameterPackLocation() const { return NameLoc; } + + /// \brief Iterators over the parameters which the parameter pack expanded + /// into. + typedef ParmVarDecl * const *iterator; + iterator begin() const { return reinterpret_cast<iterator>(this+1); } + iterator end() const { return begin() + NumParameters; } + + /// \brief Get the number of parameters in this parameter pack. + unsigned getNumExpansions() const { return NumParameters; } + + /// \brief Get an expansion of the parameter pack by index. + ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; } + + SourceRange getSourceRange() const LLVM_READONLY { return NameLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == FunctionParmPackExprClass; + } + + child_range children() { return child_range(); } +}; + /// \brief Represents a prvalue temporary that written into memory so that /// a reference can bind to it. /// @@ -3670,9 +3691,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == MaterializeTemporaryExprClass; } - static bool classof(const MaterializeTemporaryExpr *) { - return true; - } // Iterators child_range children() { return child_range(&Temporary, &Temporary + 1); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h index 93a5ada..27f5da0 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h @@ -51,7 +51,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCStringLiteralClass; } - static bool classof(const ObjCStringLiteral *) { return true; } // Iterators child_range children() { return child_range(&String, &String+1); } @@ -81,7 +80,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCBoolLiteralExprClass; } - static bool classof(const ObjCBoolLiteralExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -121,7 +119,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCBoxedExprClass; } - static bool classof(const ObjCBoxedExpr *) { return true; } // Iterators child_range children() { return child_range(&SubExpr, &SubExpr+1); } @@ -156,7 +153,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCArrayLiteralClass; } - static bool classof(const ObjCArrayLiteral *) { return true; } /// \brief Retrieve elements of array of literals. Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); } @@ -319,7 +315,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCDictionaryLiteralClass; } - static bool classof(const ObjCDictionaryLiteral *) { return true; } // Iterators child_range children() { @@ -372,7 +367,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCEncodeExprClass; } - static bool classof(const ObjCEncodeExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -409,7 +403,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSelectorExprClass; } - static bool classof(const ObjCSelectorExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -447,7 +440,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCProtocolExprClass; } - static bool classof(const ObjCProtocolExpr *) { return true; } // Iterators child_range children() { return child_range(); } @@ -501,7 +493,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIvarRefExprClass; } - static bool classof(const ObjCIvarRefExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base+1); } @@ -715,7 +706,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCPropertyRefExprClass; } - static bool classof(const ObjCPropertyRefExpr *) { return true; } // Iterators child_range children() { @@ -813,7 +803,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSubscriptRefExprClass; } - static bool classof(const ObjCSubscriptRefExpr *) { return true; } Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); } void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; } @@ -1156,10 +1145,8 @@ public: return getReceiverKind() == Class || getReceiverKind() == SuperClass; } - /// \brief Returns the receiver of an instance message. - /// - /// \brief Returns the object expression for an instance message, or - /// NULL for a message that is not an instance message. + /// \brief Returns the object expression (receiver) for an instance message, + /// or null for a message that is not an instance message. Expr *getInstanceReceiver() { if (getReceiverKind() == Instance) return static_cast<Expr *>(getReceiverPointer()); @@ -1208,6 +1195,17 @@ public: return SourceLocation(); } + /// \brief Retrieve the receiver type to which this message is being directed. + /// + /// This routine cross-cuts all of the different kinds of message + /// sends to determine what the underlying (statically known) type + /// of the receiver will be; use \c getReceiverKind() to determine + /// whether the message is a class or an instance method, whether it + /// is a send to super or not, etc. + /// + /// \returns The type of the receiver. + QualType getReceiverType() const; + /// \brief Retrieve the Objective-C interface to which this message /// is being directed, if known. /// @@ -1344,7 +1342,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCMessageExprClass; } - static bool classof(const ObjCMessageExpr *) { return true; } // Iterators child_range children(); @@ -1409,7 +1406,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIsaExprClass; } - static bool classof(const ObjCIsaExpr *) { return true; } // Iterators child_range children() { return child_range(&Base, &Base+1); } @@ -1483,7 +1479,6 @@ public: static bool classof(const Stmt *s) { return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass; } - static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; } }; /// \brief An Objective-C "bridged" cast expression, which casts between @@ -1532,8 +1527,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCBridgedCastExprClass; } - static bool classof(const ObjCBridgedCastExpr *) { return true; } - }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h index 7aedfe2..db2bddb 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h @@ -162,7 +162,7 @@ public: } /// \brief Get the decls that are contained in a file in the Offset/Length - /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of + /// range. \p Length can be 0 to indicate a point at \p Offset instead of /// a range. virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length, SmallVectorImpl<Decl *> &Decls) {} diff --git a/contrib/llvm/tools/clang/include/clang/AST/NSAPI.h b/contrib/llvm/tools/clang/include/clang/AST/NSAPI.h index 51ae1da..f9fd1f9 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/NSAPI.h +++ b/contrib/llvm/tools/clang/include/clang/AST/NSAPI.h @@ -83,7 +83,7 @@ public: /// \brief The Objective-C NSArray selectors. Selector getNSArraySelector(NSArrayMethodKind MK) const; - /// \brief Return NSArrayMethodKind if \arg Sel is such a selector. + /// \brief Return NSArrayMethodKind if \p Sel is such a selector. llvm::Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel); /// \brief Enumerates the NSDictionary methods used to generate literals. @@ -104,7 +104,7 @@ public: /// \brief The Objective-C NSDictionary selectors. Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const; - /// \brief Return NSDictionaryMethodKind if \arg Sel is such a selector. + /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector. llvm::Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel); @@ -169,7 +169,7 @@ public: Sel == getNSNumberLiteralSelector(MK, true); } - /// \brief Return NSNumberLiteralMethodKind if \arg Sel is such a selector. + /// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector. llvm::Optional<NSNumberLiteralMethodKind> getNSNumberLiteralMethodKind(Selector Sel) const; diff --git a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h index a5aec1f..bf9e1cb 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h +++ b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h @@ -97,8 +97,7 @@ private: Specifier(Other.Specifier) { } - NestedNameSpecifier &operator=(const NestedNameSpecifier &); // do not - // implement + void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION; /// \brief Either find or insert the given nested name specifier /// mockup in the given context. diff --git a/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h b/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h index 6359414..18169fd 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h +++ b/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h @@ -288,7 +288,11 @@ enum CastKind { /// /// This particular cast kind is used for the conversion from a C++11 /// lambda expression to a block pointer. - CK_CopyAndAutoreleaseBlockObject + CK_CopyAndAutoreleaseBlockObject, + + // Convert a builtin function to a function pointer; only allowed in the + // callee of a call expression. + CK_BuiltinFnToFnPtr }; static const CastKind CK_Invalid = static_cast<CastKind>(-1); diff --git a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h index f2c015f..7babc1b 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h @@ -39,6 +39,7 @@ struct PrintingPolicy { SuppressUnwrittenScope(false), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), SuppressStrongLifetime(false), Bool(LO.Bool), + TerseOutput(false), SuppressAttributes(false), DumpSourceManager(0) { } /// \brief What language we're printing. @@ -134,6 +135,17 @@ struct PrintingPolicy { /// doesn't actually have 'bool' (because, e.g., it is defined as a macro). unsigned Bool : 1; + /// \brief Provide a 'terse' output. + /// + /// For example, in this mode we don't print function bodies, class members, + /// declarations inside namespaces etc. Effectively, this should print + /// only the requested declaration. + unsigned TerseOutput : 1; + + /// \brief When true, do not print attributes attached to the declaration. + /// + unsigned SuppressAttributes : 1; + /// \brief If we are "dumping" rather than "pretty-printing", this points to /// a SourceManager which will be used to dump SourceLocations. Dumping /// involves printing the internal details of the AST and pretty-printing diff --git a/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h b/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h index 630626b..3a8b218 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h @@ -18,6 +18,7 @@ namespace clang { class ASTContext; class ASTReader; class Decl; +class Preprocessor; namespace comments { class FullComment; @@ -114,7 +115,8 @@ public: } /// Parse the comment, assuming it is attached to decl \c D. - comments::FullComment *parse(const ASTContext &Context, const Decl *D) const; + comments::FullComment *parse(const ASTContext &Context, + const Preprocessor *PP, const Decl *D) const; private: SourceRange Range; @@ -188,7 +190,7 @@ public: private: SourceManager &SourceMgr; std::vector<RawComment *> Comments; - RawComment LastComment; + SourceLocation PrevCommentEndLoc; bool OnlyWhitespaceSeen; void addCommentsToFront(const std::vector<RawComment *> &C) { diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h index 3a870d0..3655646 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h @@ -136,8 +136,8 @@ private: void Destroy(ASTContext &Ctx); - ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT - void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT + ASTRecordLayout(const ASTRecordLayout &) LLVM_DELETED_FUNCTION; + void operator=(const ASTRecordLayout &) LLVM_DELETED_FUNCTION; public: /// getAlignment - Get the record alignment in characters. diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h index 2e56a48..f96e067 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h @@ -721,6 +721,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument( case TemplateArgument::Null: case TemplateArgument::Declaration: case TemplateArgument::Integral: + case TemplateArgument::NullPtr: return true; case TemplateArgument::Type: @@ -753,6 +754,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc( case TemplateArgument::Null: case TemplateArgument::Declaration: case TemplateArgument::Integral: + case TemplateArgument::NullPtr: return true; case TemplateArgument::Type: { @@ -799,7 +801,7 @@ bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer( if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); - if (Init->isWritten()) + if (Init->isWritten() || getDerived().shouldVisitImplicitCode()) TRY_TO(TraverseStmt(Init->getInit())); return true; } @@ -1827,7 +1829,7 @@ bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \ return true; \ } -DEF_TRAVERSE_STMT(AsmStmt, { +DEF_TRAVERSE_STMT(GCCAsmStmt, { TRY_TO(TraverseStmt(S->getAsmString())); for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) { TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I))); @@ -1836,7 +1838,7 @@ DEF_TRAVERSE_STMT(AsmStmt, { TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I))); } for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) { - TRY_TO(TraverseStmt(S->getClobber(I))); + TRY_TO(TraverseStmt(S->getClobberStringLiteral(I))); } // children() iterates over inputExpr and outputExpr. }) @@ -2141,7 +2143,9 @@ DEF_TRAVERSE_STMT(BlockExpr, { return true; // no child statements to loop through. }) DEF_TRAVERSE_STMT(ChooseExpr, { }) -DEF_TRAVERSE_STMT(CompoundLiteralExpr, { }) +DEF_TRAVERSE_STMT(CompoundLiteralExpr, { + TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); +}) DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { }) DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { }) DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { }) @@ -2219,6 +2223,7 @@ DEF_TRAVERSE_STMT(PackExpansionExpr, { }) DEF_TRAVERSE_STMT(SizeOfPackExpr, { }) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { }) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { }) +DEF_TRAVERSE_STMT(FunctionParmPackExpr, { }) DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { }) DEF_TRAVERSE_STMT(AtomicExpr, { }) diff --git a/contrib/llvm/tools/clang/include/clang/AST/SelectorLocationsKind.h b/contrib/llvm/tools/clang/include/clang/AST/SelectorLocationsKind.h index cd43a5c..6d903f8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/SelectorLocationsKind.h +++ b/contrib/llvm/tools/clang/include/clang/AST/SelectorLocationsKind.h @@ -42,7 +42,7 @@ enum SelectorLocationsKind { SelLoc_StandardWithSpace = 2 }; -/// \brief Returns true if all \arg SelLocs are in a "standard" location. +/// \brief Returns true if all \p SelLocs are in a "standard" location. SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, ArrayRef<SourceLocation> SelLocs, ArrayRef<Expr *> Args, @@ -60,7 +60,7 @@ SourceLocation getStandardSelectorLoc(unsigned Index, ArrayRef<Expr *> Args, SourceLocation EndLoc); -/// \brief Returns true if all \arg SelLocs are in a "standard" location. +/// \brief Returns true if all \p SelLocs are in a "standard" location. SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, ArrayRef<SourceLocation> SelLocs, ArrayRef<ParmVarDecl *> Args, diff --git a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h index 35fb693..a9bbb48 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h @@ -392,9 +392,6 @@ public: const_cast<const Stmt*>(this)->stripLabelLikeStatements()); } - // Implement isa<T> support. - static bool classof(const Stmt *) { return true; } - /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) /// contain implicit control-flow in the order their subexpressions /// are evaluated. This predicate returns true if this statement has @@ -424,12 +421,12 @@ public: /// \brief Produce a unique representation of the given statement. /// - /// \brief ID once the profiling operation is complete, will contain + /// \param ID once the profiling operation is complete, will contain /// the unique representation of the given statement. /// - /// \brief Context the AST context in which the statement resides + /// \param Context the AST context in which the statement resides /// - /// \brief Canonical whether the profile should be based on the canonical + /// \param Canonical whether the profile should be based on the canonical /// representation of this statement (e.g., where non-type template /// parameters are identified by index/level rather than their /// declaration pointers) or the exact representation of the statement as @@ -480,7 +477,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DeclStmtClass; } - static bool classof(const DeclStmt *) { return true; } // Iterators over subexpressions. child_range children() { @@ -535,7 +531,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == NullStmtClass; } - static bool classof(const NullStmt *) { return true; } child_range children() { return child_range(); } @@ -615,7 +610,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CompoundStmtClass; } - static bool classof(const CompoundStmt *) { return true; } // Iterators child_range children() { @@ -654,7 +648,6 @@ public: return T->getStmtClass() == CaseStmtClass || T->getStmtClass() == DefaultStmtClass; } - static bool classof(const SwitchCase *) { return true; } }; class CaseStmt : public SwitchCase { @@ -714,7 +707,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CaseStmtClass; } - static bool classof(const CaseStmt *) { return true; } // Iterators child_range children() { @@ -749,7 +741,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DefaultStmtClass; } - static bool classof(const DefaultStmt *) { return true; } // Iterators child_range children() { return child_range(&SubStmt, &SubStmt+1); } @@ -788,7 +779,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == LabelStmtClass; } - static bool classof(const LabelStmt *) { return true; } }; @@ -837,7 +827,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == AttributedStmtClass; } - static bool classof(const AttributedStmt *) { return true; } }; @@ -906,7 +895,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == IfStmtClass; } - static bool classof(const IfStmt *) { return true; } }; /// SwitchStmt - This represents a 'switch' stmt. @@ -1000,7 +988,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == SwitchStmtClass; } - static bool classof(const SwitchStmt *) { return true; } }; @@ -1050,7 +1037,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == WhileStmtClass; } - static bool classof(const WhileStmt *) { return true; } // Iterators child_range children() { @@ -1099,7 +1085,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == DoStmtClass; } - static bool classof(const DoStmt *) { return true; } // Iterators child_range children() { @@ -1171,7 +1156,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ForStmtClass; } - static bool classof(const ForStmt *) { return true; } // Iterators child_range children() { @@ -1206,7 +1190,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == GotoStmtClass; } - static bool classof(const GotoStmt *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1251,7 +1234,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == IndirectGotoStmtClass; } - static bool classof(const IndirectGotoStmt *) { return true; } // Iterators child_range children() { return child_range(&Target, &Target+1); } @@ -1278,7 +1260,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ContinueStmtClass; } - static bool classof(const ContinueStmt *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1302,7 +1283,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == BreakStmtClass; } - static bool classof(const BreakStmt *) { return true; } // Iterators child_range children() { return child_range(); } @@ -1354,7 +1334,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ReturnStmtClass; } - static bool classof(const ReturnStmt *) { return true; } // Iterators child_range children() { @@ -1363,48 +1342,184 @@ public: } }; -/// AsmStmt - This represents a GNU inline-assembly statement extension. +/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt. /// class AsmStmt : public Stmt { - SourceLocation AsmLoc, RParenLoc; - StringLiteral *AsmStr; - +protected: + SourceLocation AsmLoc; + /// \brief True if the assembly statement does not have any input or output + /// operands. bool IsSimple; + + /// \brief If true, treat this inline assembly as having side effects. + /// This assembly statement should not be optimized, deleted or moved. bool IsVolatile; - bool MSAsm; unsigned NumOutputs; unsigned NumInputs; unsigned NumClobbers; - // FIXME: If we wanted to, we could allocate all of these in one big array. IdentifierInfo **Names; - StringLiteral **Constraints; Stmt **Exprs; - StringLiteral **Clobbers; -public: - AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, - bool msasm, unsigned numoutputs, unsigned numinputs, - IdentifierInfo **names, StringLiteral **constraints, - Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, - StringLiteral **clobbers, SourceLocation rparenloc); + AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile, + unsigned numoutputs, unsigned numinputs, unsigned numclobbers) : + Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile), + NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { } +public: /// \brief Build an empty inline-assembly statement. - explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty), - Names(0), Constraints(0), Exprs(0), Clobbers(0) { } + explicit AsmStmt(StmtClass SC, EmptyShell Empty) : + Stmt(SC, Empty), Names(0), Exprs(0) { } SourceLocation getAsmLoc() const { return AsmLoc; } void setAsmLoc(SourceLocation L) { AsmLoc = L; } - SourceLocation getRParenLoc() const { return RParenLoc; } - void setRParenLoc(SourceLocation L) { RParenLoc = L; } - bool isVolatile() const { return IsVolatile; } - void setVolatile(bool V) { IsVolatile = V; } bool isSimple() const { return IsSimple; } void setSimple(bool V) { IsSimple = V; } - bool isMSAsm() const { return MSAsm; } - void setMSAsm(bool V) { MSAsm = V; } + + bool isVolatile() const { return IsVolatile; } + void setVolatile(bool V) { IsVolatile = V; } + + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); } + + //===--- Asm String Analysis ---===// + + /// Assemble final IR asm string. + std::string generateAsmString(ASTContext &C) const; + + //===--- Output operands ---===// + + unsigned getNumOutputs() const { return NumOutputs; } + + IdentifierInfo *getOutputIdentifier(unsigned i) const { + return Names[i]; + } + + StringRef getOutputName(unsigned i) const { + if (IdentifierInfo *II = getOutputIdentifier(i)) + return II->getName(); + + return StringRef(); + } + + /// getOutputConstraint - Return the constraint string for the specified + /// output operand. All output constraints are known to be non-empty (either + /// '=' or '+'). + StringRef getOutputConstraint(unsigned i) const; + + /// isOutputPlusConstraint - Return true if the specified output constraint + /// is a "+" constraint (which is both an input and an output) or false if it + /// is an "=" constraint (just an output). + bool isOutputPlusConstraint(unsigned i) const { + return getOutputConstraint(i)[0] == '+'; + } + + const Expr *getOutputExpr(unsigned i) const; + + /// getNumPlusOperands - Return the number of output operands that have a "+" + /// constraint. + unsigned getNumPlusOperands() const; + + //===--- Input operands ---===// + + unsigned getNumInputs() const { return NumInputs; } + + IdentifierInfo *getInputIdentifier(unsigned i) const { + return Names[i + NumOutputs]; + } + + StringRef getInputName(unsigned i) const { + if (IdentifierInfo *II = getInputIdentifier(i)) + return II->getName(); + + return StringRef(); + } + + /// getInputConstraint - Return the specified input constraint. Unlike output + /// constraints, these can be empty. + StringRef getInputConstraint(unsigned i) const; + + const Expr *getInputExpr(unsigned i) const; + + //===--- Other ---===// + + unsigned getNumClobbers() const { return NumClobbers; } + StringRef getClobber(unsigned i) const; + + static bool classof(const Stmt *T) { + return T->getStmtClass() == GCCAsmStmtClass || + T->getStmtClass() == MSAsmStmtClass; + } + + // Input expr iterators. + + typedef ExprIterator inputs_iterator; + typedef ConstExprIterator const_inputs_iterator; + + inputs_iterator begin_inputs() { + return &Exprs[0] + NumOutputs; + } + + inputs_iterator end_inputs() { + return &Exprs[0] + NumOutputs + NumInputs; + } + + const_inputs_iterator begin_inputs() const { + return &Exprs[0] + NumOutputs; + } + + const_inputs_iterator end_inputs() const { + return &Exprs[0] + NumOutputs + NumInputs; + } + + // Output expr iterators. + + typedef ExprIterator outputs_iterator; + typedef ConstExprIterator const_outputs_iterator; + + outputs_iterator begin_outputs() { + return &Exprs[0]; + } + outputs_iterator end_outputs() { + return &Exprs[0] + NumOutputs; + } + + const_outputs_iterator begin_outputs() const { + return &Exprs[0]; + } + const_outputs_iterator end_outputs() const { + return &Exprs[0] + NumOutputs; + } + + child_range children() { + return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); + } +}; + +/// This represents a GCC inline-assembly statement extension. +/// +class GCCAsmStmt : public AsmStmt { + SourceLocation RParenLoc; + StringLiteral *AsmStr; + + // FIXME: If we wanted to, we could allocate all of these in one big array. + StringLiteral **Constraints; + StringLiteral **Clobbers; + +public: + GCCAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, + bool isvolatile, unsigned numoutputs, unsigned numinputs, + IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, + StringLiteral *asmstr, unsigned numclobbers, + StringLiteral **clobbers, SourceLocation rparenloc); + + /// \brief Build an empty inline-assembly statement. + explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty), + Constraints(0), Clobbers(0) { } + + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } //===--- Asm String Analysis ---===// @@ -1461,25 +1576,11 @@ public: unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces, ASTContext &C, unsigned &DiagOffs) const; + /// Assemble final IR asm string. + std::string generateAsmString(ASTContext &C) const; //===--- Output operands ---===// - unsigned getNumOutputs() const { return NumOutputs; } - - IdentifierInfo *getOutputIdentifier(unsigned i) const { - return Names[i]; - } - - StringRef getOutputName(unsigned i) const { - if (IdentifierInfo *II = getOutputIdentifier(i)) - return II->getName(); - - return StringRef(); - } - - /// getOutputConstraint - Return the constraint string for the specified - /// output operand. All output constraints are known to be non-empty (either - /// '=' or '+'). StringRef getOutputConstraint(unsigned i) const; const StringLiteral *getOutputConstraintLiteral(unsigned i) const { @@ -1492,37 +1593,11 @@ public: Expr *getOutputExpr(unsigned i); const Expr *getOutputExpr(unsigned i) const { - return const_cast<AsmStmt*>(this)->getOutputExpr(i); + return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i); } - /// isOutputPlusConstraint - Return true if the specified output constraint - /// is a "+" constraint (which is both an input and an output) or false if it - /// is an "=" constraint (just an output). - bool isOutputPlusConstraint(unsigned i) const { - return getOutputConstraint(i)[0] == '+'; - } - - /// getNumPlusOperands - Return the number of output operands that have a "+" - /// constraint. - unsigned getNumPlusOperands() const; - //===--- Input operands ---===// - unsigned getNumInputs() const { return NumInputs; } - - IdentifierInfo *getInputIdentifier(unsigned i) const { - return Names[i + NumOutputs]; - } - - StringRef getInputName(unsigned i) const { - if (IdentifierInfo *II = getInputIdentifier(i)) - return II->getName(); - - return StringRef(); - } - - /// getInputConstraint - Return the specified input constraint. Unlike output - /// constraints, these can be empty. StringRef getInputConstraint(unsigned i) const; const StringLiteral *getInputConstraintLiteral(unsigned i) const { @@ -1536,7 +1611,7 @@ public: void setInputExpr(unsigned i, Expr *E); const Expr *getInputExpr(unsigned i) const { - return const_cast<AsmStmt*>(this)->getInputExpr(i); + return const_cast<GCCAsmStmt*>(this)->getInputExpr(i); } void setOutputsAndInputsAndClobbers(ASTContext &C, @@ -1555,90 +1630,45 @@ public: /// This returns -1 if the operand name is invalid. int getNamedOperand(StringRef SymbolicName) const; - unsigned getNumClobbers() const { return NumClobbers; } - StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } - const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } + StringRef getClobber(unsigned i) const; + StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; } + const StringLiteral *getClobberStringLiteral(unsigned i) const { + return Clobbers[i]; + } SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(AsmLoc, RParenLoc); } - static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} - static bool classof(const AsmStmt *) { return true; } - - // Input expr iterators. - - typedef ExprIterator inputs_iterator; - typedef ConstExprIterator const_inputs_iterator; - - inputs_iterator begin_inputs() { - return &Exprs[0] + NumOutputs; - } - - inputs_iterator end_inputs() { - return &Exprs[0] + NumOutputs + NumInputs; - } - - const_inputs_iterator begin_inputs() const { - return &Exprs[0] + NumOutputs; - } - - const_inputs_iterator end_inputs() const { - return &Exprs[0] + NumOutputs + NumInputs; - } - - // Output expr iterators. - - typedef ExprIterator outputs_iterator; - typedef ConstExprIterator const_outputs_iterator; - - outputs_iterator begin_outputs() { - return &Exprs[0]; - } - outputs_iterator end_outputs() { - return &Exprs[0] + NumOutputs; - } - - const_outputs_iterator begin_outputs() const { - return &Exprs[0]; - } - const_outputs_iterator end_outputs() const { - return &Exprs[0] + NumOutputs; - } - - child_range children() { - return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); + static bool classof(const Stmt *T) { + return T->getStmtClass() == GCCAsmStmtClass; } }; -/// MSAsmStmt - This represents a MS inline-assembly statement extension. +/// This represents a Microsoft inline-assembly statement extension. /// -class MSAsmStmt : public Stmt { +class MSAsmStmt : public AsmStmt { SourceLocation AsmLoc, LBraceLoc, EndLoc; std::string AsmStr; - bool IsSimple; - bool IsVolatile; - unsigned NumAsmToks; - unsigned NumInputs; - unsigned NumOutputs; - unsigned NumClobbers; Token *AsmToks; - IdentifierInfo **Names; - Stmt **Exprs; + StringRef *Constraints; StringRef *Clobbers; public: MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc, bool issimple, bool isvolatile, ArrayRef<Token> asmtoks, - ArrayRef<IdentifierInfo*> inputs, ArrayRef<IdentifierInfo*> outputs, - StringRef asmstr, ArrayRef<StringRef> clobbers, - SourceLocation endloc); + unsigned numoutputs, unsigned numinputs, + ArrayRef<IdentifierInfo*> names, ArrayRef<StringRef> constraints, + ArrayRef<Expr*> exprs, StringRef asmstr, + ArrayRef<StringRef> clobbers, SourceLocation endloc); + + /// \brief Build an empty MS-style inline-assembly statement. + explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty), + NumAsmToks(0), AsmToks(0), Constraints(0), Clobbers(0) { } - SourceLocation getAsmLoc() const { return AsmLoc; } - void setAsmLoc(SourceLocation L) { AsmLoc = L; } SourceLocation getLBraceLoc() const { return LBraceLoc; } void setLBraceLoc(SourceLocation L) { LBraceLoc = L; } SourceLocation getEndLoc() const { return EndLoc; } @@ -1649,20 +1679,42 @@ public: unsigned getNumAsmToks() { return NumAsmToks; } Token *getAsmToks() { return AsmToks; } - bool isVolatile() const { return IsVolatile; } - void setVolatile(bool V) { IsVolatile = V; } - bool isSimple() const { return IsSimple; } - void setSimple(bool V) { IsSimple = V; } - //===--- Asm String Analysis ---===// const std::string *getAsmString() const { return &AsmStr; } std::string *getAsmString() { return &AsmStr; } void setAsmString(StringRef &E) { AsmStr = E.str(); } + /// Assemble final IR asm string. + std::string generateAsmString(ASTContext &C) const; + + //===--- Output operands ---===// + + StringRef getOutputConstraint(unsigned i) const { + return Constraints[i]; + } + + Expr *getOutputExpr(unsigned i); + + const Expr *getOutputExpr(unsigned i) const { + return const_cast<MSAsmStmt*>(this)->getOutputExpr(i); + } + + //===--- Input operands ---===// + + StringRef getInputConstraint(unsigned i) const { + return Constraints[i + NumOutputs]; + } + + Expr *getInputExpr(unsigned i); + void setInputExpr(unsigned i, Expr *E); + + const Expr *getInputExpr(unsigned i) const { + return const_cast<MSAsmStmt*>(this)->getInputExpr(i); + } + //===--- Other ---===// - unsigned getNumClobbers() const { return NumClobbers; } StringRef getClobber(unsigned i) const { return Clobbers[i]; } SourceRange getSourceRange() const LLVM_READONLY { @@ -1671,7 +1723,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == MSAsmStmtClass; } - static bool classof(const MSAsmStmt *) { return true; } child_range children() { return child_range(&Exprs[0], &Exprs[0]); @@ -1720,8 +1771,6 @@ public: return T->getStmtClass() == SEHExceptStmtClass; } - static bool classof(SEHExceptStmt *) { return true; } - }; class SEHFinallyStmt : public Stmt { @@ -1757,8 +1806,6 @@ public: return T->getStmtClass() == SEHFinallyStmtClass; } - static bool classof(SEHFinallyStmt *) { return true; } - }; class SEHTryStmt : public Stmt { @@ -1810,8 +1857,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == SEHTryStmtClass; } - - static bool classof(SEHTryStmt *) { return true; } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h index a948722..f4e4dcd 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h @@ -50,7 +50,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXCatchStmtClass; } - static bool classof(const CXXCatchStmt *) { return true; } child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); } @@ -111,7 +110,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTryStmtClass; } - static bool classof(const CXXTryStmt *) { return true; } child_range children() { return child_range(getStmts(), getStmts() + getNumHandlers() + 1); @@ -196,7 +194,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXForRangeStmtClass; } - static bool classof(const CXXForRangeStmt *) { return true; } // Iterators child_range children() { @@ -286,8 +283,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == MSDependentExistsStmtClass; } - - static bool classof(MSDependentExistsStmt *) { return true; } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h b/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h index e7e1232..d7a73a7 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h @@ -61,7 +61,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCForCollectionStmtClass; } - static bool classof(const ObjCForCollectionStmt *) { return true; } // Iterators child_range children() { @@ -112,7 +111,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtCatchStmtClass; } - static bool classof(const ObjCAtCatchStmt *) { return true; } child_range children() { return child_range(&Body, &Body + 1); } }; @@ -143,7 +141,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtFinallyStmtClass; } - static bool classof(const ObjCAtFinallyStmt *) { return true; } child_range children() { return child_range(&AtFinallyStmt, &AtFinallyStmt+1); @@ -244,7 +241,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtTryStmtClass; } - static bool classof(const ObjCAtTryStmt *) { return true; } child_range children() { return child_range(getStmts(), @@ -303,7 +299,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtSynchronizedStmtClass; } - static bool classof(const ObjCAtSynchronizedStmt *) { return true; } child_range children() { return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR); @@ -339,7 +334,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAtThrowStmtClass; } - static bool classof(const ObjCAtThrowStmt *) { return true; } child_range children() { return child_range(&Throw, &Throw+1); } }; @@ -371,7 +365,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAutoreleasePoolStmtClass; } - static bool classof(const ObjCAutoreleasePoolStmt *) { return true; } child_range children() { return child_range(&SubStmt, &SubStmt + 1); } }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h index 5047028..1c0abde 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h @@ -28,11 +28,11 @@ namespace llvm { namespace clang { -class Decl; class DiagnosticBuilder; class Expr; struct PrintingPolicy; class TypeSourceInfo; +class ValueDecl; /// \brief Represents a template argument within a class template /// specialization. @@ -43,12 +43,14 @@ public: /// \brief Represents an empty template argument, e.g., one that has not /// been deduced. Null = 0, - /// The template argument is a type. Its value is stored in the - /// TypeOrValue field. + /// The template argument is a type. Type, - /// The template argument is a declaration that was provided for a pointer - /// or reference non-type template parameter. + /// The template argument is a declaration that was provided for a pointer, + /// reference, or pointer to member non-type template parameter. Declaration, + /// The template argument is a null pointer or null pointer to member that + /// was provided for a non-type template parameter. + NullPtr, /// The template argument is an integral value stored in an llvm::APSInt /// that was provided for an integral non-type template parameter. Integral, @@ -73,6 +75,10 @@ private: union { uintptr_t TypeOrValue; struct { + ValueDecl *D; + bool ForRefParam; + } DeclArg; + struct { // We store a decomposed APSInt with the data allocated by ASTContext if // BitWidth > 64. The memory may be shared between multiple // TemplateArgument instances. @@ -101,15 +107,18 @@ public: TemplateArgument() : Kind(Null), TypeOrValue(0) { } /// \brief Construct a template type argument. - TemplateArgument(QualType T) : Kind(Type) { + TemplateArgument(QualType T, bool isNullPtr = false) + : Kind(isNullPtr ? NullPtr : Type) { TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); } /// \brief Construct a template argument that refers to a /// declaration, which is either an external declaration or a /// template declaration. - TemplateArgument(Decl *D) : Kind(Declaration) { - TypeOrValue = reinterpret_cast<uintptr_t>(D); + TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) { + assert(D && "Expected decl"); + DeclArg.D = D; + DeclArg.ForRefParam = ForRefParam; } /// \brief Construct an integral constant template argument. The memory to @@ -177,6 +186,10 @@ public: this->Args.NumArgs = NumArgs; } + static TemplateArgument getEmptyPack() { + return TemplateArgument((TemplateArgument*)0, 0); + } + /// \brief Create a new template argument pack by copying the given set of /// template arguments. static TemplateArgument CreatePackCopy(ASTContext &Context, @@ -205,34 +218,43 @@ public: /// \brief Determine whether this template argument is a pack expansion. bool isPackExpansion() const; - /// \brief Retrieve the template argument as a type. + /// \brief Retrieve the type for a type template argument. QualType getAsType() const { - if (Kind != Type) - return QualType(); - + assert(Kind == Type && "Unexpected kind"); return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); } - /// \brief Retrieve the template argument as a declaration. - Decl *getAsDecl() const { - if (Kind != Declaration) - return 0; - return reinterpret_cast<Decl *>(TypeOrValue); + /// \brief Retrieve the declaration for a declaration non-type + /// template argument. + ValueDecl *getAsDecl() const { + assert(Kind == Declaration && "Unexpected kind"); + return DeclArg.D; + } + + /// \brief Retrieve whether a declaration is binding to a + /// reference parameter in a declaration non-type template argument. + bool isDeclForReferenceParam() const { + assert(Kind == Declaration && "Unexpected kind"); + return DeclArg.ForRefParam; } - /// \brief Retrieve the template argument as a template name. + /// \brief Retrieve the type for null non-type template argument. + QualType getNullPtrType() const { + assert(Kind == NullPtr && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); + } + + /// \brief Retrieve the template name for a template name argument. TemplateName getAsTemplate() const { - if (Kind != Template) - return TemplateName(); - + assert(Kind == Template && "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); } /// \brief Retrieve the template argument as a template name; if the argument /// is a pack expansion, return the pattern as a template name. TemplateName getAsTemplateOrTemplatePattern() const { - if (Kind != Template && Kind != TemplateExpansion) - return TemplateName(); + assert((Kind == Template || Kind == TemplateExpansion) && + "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); } @@ -244,6 +266,7 @@ public: /// \brief Retrieve the template argument as an integral value. // FIXME: Provide a way to read the integral data without copying the value. llvm::APSInt getAsIntegral() const { + assert(Kind == Integral && "Unexpected kind"); using namespace llvm; if (Integer.BitWidth <= 64) return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); @@ -255,23 +278,18 @@ public: /// \brief Retrieve the type of the integral value. QualType getIntegralType() const { - if (Kind != Integral) - return QualType(); - + assert(Kind == Integral && "Unexpected kind"); return QualType::getFromOpaquePtr(Integer.Type); } void setIntegralType(QualType T) { - assert(Kind == Integral && - "Cannot set the integral type of a non-integral template argument"); + assert(Kind == Integral && "Unexpected kind"); Integer.Type = T.getAsOpaquePtr(); } /// \brief Retrieve the template argument as an expression. Expr *getAsExpr() const { - if (Kind != Expression) - return 0; - + assert(Kind == Expression && "Unexpected kind"); return reinterpret_cast<Expr *>(TypeOrValue); } @@ -436,7 +454,17 @@ public: assert(Argument.getKind() == TemplateArgument::Declaration); return LocInfo.getAsExpr(); } - + + Expr *getSourceNullPtrExpression() const { + assert(Argument.getKind() == TemplateArgument::NullPtr); + return LocInfo.getAsExpr(); + } + + Expr *getSourceIntegralExpression() const { + assert(Argument.getKind() == TemplateArgument::Integral); + return LocInfo.getAsExpr(); + } + NestedNameSpecifierLoc getTemplateQualifierLoc() const { assert(Argument.getKind() == TemplateArgument::Template || Argument.getKind() == TemplateArgument::TemplateExpansion); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Type.h b/contrib/llvm/tools/clang/include/clang/AST/Type.h index 6564b66..6900a7d 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Type.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Type.h @@ -20,6 +20,7 @@ #include "clang/Basic/Linkage.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/Visibility.h" +#include "clang/Basic/Specifiers.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" #include "llvm/Support/type_traits.h" @@ -160,6 +161,44 @@ public: Qualifiers() : Mask(0) {} + /// \brief Returns the common set of qualifiers while removing them from + /// the given sets. + static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { + // If both are only CVR-qualified, bit operations are sufficient. + if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { + Qualifiers Q; + Q.Mask = L.Mask & R.Mask; + L.Mask &= ~Q.Mask; + R.Mask &= ~Q.Mask; + return Q; + } + + Qualifiers Q; + unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); + Q.addCVRQualifiers(CommonCRV); + L.removeCVRQualifiers(CommonCRV); + R.removeCVRQualifiers(CommonCRV); + + if (L.getObjCGCAttr() == R.getObjCGCAttr()) { + Q.setObjCGCAttr(L.getObjCGCAttr()); + L.removeObjCGCAttr(); + R.removeObjCGCAttr(); + } + + if (L.getObjCLifetime() == R.getObjCLifetime()) { + Q.setObjCLifetime(L.getObjCLifetime()); + L.removeObjCLifetime(); + R.removeObjCLifetime(); + } + + if (L.getAddressSpace() == R.getAddressSpace()) { + Q.setAddressSpace(L.getAddressSpace()); + L.removeAddressSpace(); + R.removeAddressSpace(); + } + return Q; + } + static Qualifiers fromFastMask(unsigned Mask) { Qualifiers Qs; Qs.addFastQualifiers(Mask); @@ -333,6 +372,23 @@ public: } } + /// \brief Remove the qualifiers from the given set from this set. + void removeQualifiers(Qualifiers Q) { + // If the other set doesn't have any non-boolean qualifiers, just + // bit-and the inverse in. + if (!(Q.Mask & ~CVRMask)) + Mask &= ~Q.Mask; + else { + Mask &= ~(Q.Mask & CVRMask); + if (getObjCGCAttr() == Q.getObjCGCAttr()) + removeObjCGCAttr(); + if (getObjCLifetime() == Q.getObjCLifetime()) + removeObjCLifetime(); + if (getAddressSpace() == Q.getAddressSpace()) + removeAddressSpace(); + } + } + /// \brief Add the qualifiers from the given set to this set, given that /// they don't conflict. void addConsistentQualifiers(Qualifiers qs) { @@ -400,7 +456,7 @@ public: } Qualifiers &operator-=(Qualifiers R) { - Mask = Mask & ~(R.Mask); + removeQualifiers(R); return *this; } @@ -435,18 +491,6 @@ private: static const uint32_t AddressSpaceShift = 8; }; -/// CallingConv - Specifies the calling convention that a function uses. -enum CallingConv { - CC_Default, - CC_C, // __attribute__((cdecl)) - CC_X86StdCall, // __attribute__((stdcall)) - CC_X86FastCall, // __attribute__((fastcall)) - CC_X86ThisCall, // __attribute__((thiscall)) - CC_X86Pascal, // __attribute__((pascal)) - CC_AAPCS, // __attribute__((pcs("aapcs"))) - CC_AAPCS_VFP // __attribute__((pcs("aapcs-vfp"))) -}; - /// A std::pair-like structure for storing a qualified type split /// into its local qualifiers and its locally-unqualified type. struct SplitQualType { @@ -1126,8 +1170,8 @@ public: }; private: - Type(const Type&); // DO NOT IMPLEMENT. - void operator=(const Type&); // DO NOT IMPLEMENT. + Type(const Type &) LLVM_DELETED_FUNCTION; + void operator=(const Type &) LLVM_DELETED_FUNCTION; /// Bitfields required by the Type class. class TypeBitfields { @@ -1225,7 +1269,7 @@ protected: /// Extra information which affects how the function is called, like /// regparm and the calling convention. - unsigned ExtInfo : 8; + unsigned ExtInfo : 9; /// TypeQuals - Used only by FunctionProtoType, put here to pack with the /// other bitfields. @@ -1512,6 +1556,7 @@ public: bool isRecordType() const; bool isClassType() const; bool isStructureType() const; + bool isInterfaceType() const; bool isStructureOrClassType() const; bool isUnionType() const; bool isComplexIntegerType() const; // GCC _Complex integer type. @@ -1630,13 +1675,19 @@ public: const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; - const CXXRecordDecl *getCXXRecordDeclForPointerType() const; /// \brief Retrieves the CXXRecordDecl that this type refers to, either /// because the type is a RecordType or because it is the injected-class-name /// type of a class template or class template partial specialization. CXXRecordDecl *getAsCXXRecordDecl() const; + /// If this is a pointer or reference to a RecordType, return the + /// CXXRecordDecl that that type refers to. + /// + /// If this is not a pointer or reference, or the type being pointed to does + /// not refer to a CXXRecordDecl, returns NULL. + const CXXRecordDecl *getPointeeCXXRecordDecl() const; + /// \brief Get the AutoType whose type will be deduced for a variable with /// an initializer of this type. This looks through declarators like pointer /// types, but not through decltype or typedefs. @@ -1738,8 +1789,6 @@ public: CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h LLVM_ATTRIBUTE_USED void dump() const; - static bool classof(const Type *) { return true; } - friend class ASTReader; friend class ASTWriter; }; @@ -1748,6 +1797,11 @@ public: /// until it reaches a TypedefType or a non-sugared type. template <> const TypedefType *Type::getAs() const; +/// \brief This will check for a TemplateSpecializationType by removing any +/// existing sugar until it reaches a TemplateSpecializationType or a +/// non-sugared type. +template <> const TemplateSpecializationType *Type::getAs() const; + // We can do canonical leaf types faster, because we don't have to // worry about preserving child type decoration. #define TYPE(Class, Base) @@ -1834,7 +1888,6 @@ public: } static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } - static bool classof(const BuiltinType *) { return true; } }; /// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex @@ -1865,7 +1918,6 @@ public: } static bool classof(const Type *T) { return T->getTypeClass() == Complex; } - static bool classof(const ComplexType *) { return true; } }; /// ParenType - Sugar for parentheses used when specifying types. @@ -1897,7 +1949,6 @@ public: } static bool classof(const Type *T) { return T->getTypeClass() == Paren; } - static bool classof(const ParenType *) { return true; } }; /// PointerType - C99 6.7.5.1 - Pointer Declarators. @@ -1929,7 +1980,6 @@ public: } static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } - static bool classof(const PointerType *) { return true; } }; /// BlockPointerType - pointer to a block type. @@ -1965,7 +2015,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == BlockPointer; } - static bool classof(const BlockPointerType *) { return true; } }; /// ReferenceType - Base for LValueReferenceType and RValueReferenceType @@ -2013,7 +2062,6 @@ public: return T->getTypeClass() == LValueReference || T->getTypeClass() == RValueReference; } - static bool classof(const ReferenceType *) { return true; } }; /// LValueReferenceType - C++ [dcl.ref] - Lvalue reference @@ -2031,7 +2079,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == LValueReference; } - static bool classof(const LValueReferenceType *) { return true; } }; /// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference @@ -2048,7 +2095,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == RValueReference; } - static bool classof(const RValueReferenceType *) { return true; } }; /// MemberPointerType - C++ 8.3.3 - Pointers to members @@ -2103,7 +2149,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == MemberPointer; } - static bool classof(const MemberPointerType *) { return true; } }; /// ArrayType - C99 6.7.5.2 - Array Declarators. @@ -2159,7 +2204,6 @@ public: T->getTypeClass() == IncompleteArray || T->getTypeClass() == DependentSizedArray; } - static bool classof(const ArrayType *) { return true; } }; /// ConstantArrayType - This class represents the canonical version of @@ -2211,7 +2255,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == ConstantArray; } - static bool classof(const ConstantArrayType *) { return true; } }; /// IncompleteArrayType - This class represents C arrays with an unspecified @@ -2231,7 +2274,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == IncompleteArray; } - static bool classof(const IncompleteArrayType *) { return true; } friend class StmtIteratorBase; @@ -2294,7 +2336,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == VariableArray; } - static bool classof(const VariableArrayType *) { return true; } friend class StmtIteratorBase; @@ -2351,7 +2392,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == DependentSizedArray; } - static bool classof(const DependentSizedArrayType *) { return true; } friend class StmtIteratorBase; @@ -2397,7 +2437,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == DependentSizedExtVector; } - static bool classof(const DependentSizedExtVectorType *) { return true; } void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Context, getElementType(), getSizeExpr()); @@ -2463,7 +2502,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector; } - static bool classof(const VectorType *) { return true; } }; /// ExtVectorType - Extended vector type. This type is created using @@ -2529,7 +2567,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == ExtVector; } - static bool classof(const ExtVectorType *) { return true; } }; /// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base @@ -2561,19 +2598,19 @@ class FunctionType : public Type { // * AST read and write // * Codegen class ExtInfo { - // Feel free to rearrange or add bits, but if you go over 8, + // Feel free to rearrange or add bits, but if you go over 9, // you'll need to adjust both the Bits field below and // Type::FunctionTypeBitfields. // | CC |noreturn|produces|regparm| - // |0 .. 2| 3 | 4 | 5 .. 7| + // |0 .. 3| 4 | 5 | 6 .. 8| // // regparm is either 0 (no regparm attribute) or the regparm value+1. - enum { CallConvMask = 0x7 }; - enum { NoReturnMask = 0x8 }; - enum { ProducesResultMask = 0x10 }; + enum { CallConvMask = 0xF }; + enum { NoReturnMask = 0x10 }; + enum { ProducesResultMask = 0x20 }; enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask), - RegParmOffset = 5 }; // Assumed to be the last field + RegParmOffset = 6 }; // Assumed to be the last field uint16_t Bits; @@ -2692,7 +2729,6 @@ public: return T->getTypeClass() == FunctionNoProto || T->getTypeClass() == FunctionProto; } - static bool classof(const FunctionType *) { return true; } }; /// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has @@ -2724,7 +2760,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == FunctionNoProto; } - static bool classof(const FunctionNoProtoType *) { return true; } }; /// FunctionProtoType - Represents a prototype with argument type info, e.g. @@ -2972,14 +3007,13 @@ public: // FIXME: Remove the string version. void printExceptionSpecification(std::string &S, - PrintingPolicy Policy) const; + const PrintingPolicy &Policy) const; void printExceptionSpecification(raw_ostream &OS, - PrintingPolicy Policy) const; + const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == FunctionProto; } - static bool classof(const FunctionProtoType *) { return true; } void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, @@ -3010,7 +3044,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == UnresolvedUsing; } - static bool classof(const UnresolvedUsingType *) { return true; } void Profile(llvm::FoldingSetNodeID &ID) { return Profile(ID, Decl); @@ -3042,7 +3075,6 @@ public: QualType desugar() const; static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } - static bool classof(const TypedefType *) { return true; } }; /// TypeOfExprType (GCC extension). @@ -3062,7 +3094,6 @@ public: bool isSugared() const; static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } - static bool classof(const TypeOfExprType *) { return true; } }; /// \brief Internal representation of canonical, dependent @@ -3109,7 +3140,6 @@ public: bool isSugared() const { return true; } static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } - static bool classof(const TypeOfType *) { return true; } }; /// DecltypeType (C++0x) @@ -3131,7 +3161,6 @@ public: bool isSugared() const; static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } - static bool classof(const DecltypeType *) { return true; } }; /// \brief Internal representation of canonical, dependent @@ -3184,7 +3213,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == UnaryTransform; } - static bool classof(const UnaryTransformType *) { return true; } }; class TagType : public Type { @@ -3207,7 +3235,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast; } - static bool classof(const TagType *) { return true; } }; /// RecordType - This is a helper class that allows the use of isa/cast/dyncast @@ -3234,7 +3261,6 @@ public: QualType desugar() const { return QualType(this, 0); } static bool classof(const Type *T) { return T->getTypeClass() == Record; } - static bool classof(const RecordType *) { return true; } }; /// EnumType - This is a helper class that allows the use of isa/cast/dyncast @@ -3253,7 +3279,6 @@ public: QualType desugar() const { return QualType(this, 0); } static bool classof(const Type *T) { return T->getTypeClass() == Enum; } - static bool classof(const EnumType *) { return true; } }; /// AttributedType - An attributed type is a type to which a type @@ -3297,7 +3322,8 @@ public: attr_fastcall, attr_stdcall, attr_thiscall, - attr_pascal + attr_pascal, + attr_pnaclcall }; private: @@ -3341,7 +3367,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Attributed; } - static bool classof(const AttributedType *T) { return true; } }; class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { @@ -3415,7 +3440,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == TemplateTypeParm; } - static bool classof(const TemplateTypeParmType *T) { return true; } }; /// \brief Represents the result of substituting a type for a template @@ -3466,7 +3490,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == SubstTemplateTypeParm; } - static bool classof(const SubstTemplateTypeParmType *T) { return true; } }; /// \brief Represents the result of substituting a set of types for a template @@ -3519,7 +3542,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == SubstTemplateTypeParmPack; } - static bool classof(const SubstTemplateTypeParmPackType *T) { return true; } }; /// \brief Represents a C++0x auto type. @@ -3562,7 +3584,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Auto; } - static bool classof(const AutoType *T) { return true; } }; /// \brief Represents a type template specialization; the template @@ -3726,7 +3747,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == TemplateSpecialization; } - static bool classof(const TemplateSpecializationType *T) { return true; } }; /// \brief The injected class name of a C++ class template or class @@ -3789,13 +3809,14 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == InjectedClassName; } - static bool classof(const InjectedClassNameType *T) { return true; } }; /// \brief The kind of a tag type. enum TagTypeKind { /// \brief The "struct" keyword. TTK_Struct, + /// \brief The "__interface" keyword. + TTK_Interface, /// \brief The "union" keyword. TTK_Union, /// \brief The "class" keyword. @@ -3809,6 +3830,8 @@ enum TagTypeKind { enum ElaboratedTypeKeyword { /// \brief The "struct" keyword introduces the elaborated-type-specifier. ETK_Struct, + /// \brief The "__interface" keyword introduces the elaborated-type-specifier. + ETK_Interface, /// \brief The "union" keyword introduces the elaborated-type-specifier. ETK_Union, /// \brief The "class" keyword introduces the elaborated-type-specifier. @@ -3932,7 +3955,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; } - static bool classof(const ElaboratedType *T) { return true; } }; /// \brief Represents a qualified type name for which the type name is @@ -3996,7 +4018,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == DependentName; } - static bool classof(const DependentNameType *T) { return true; } }; /// DependentTemplateSpecializationType - Represents a template @@ -4067,9 +4088,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == DependentTemplateSpecialization; } - static bool classof(const DependentTemplateSpecializationType *T) { - return true; - } }; /// \brief Represents a pack expansion of types. @@ -4150,9 +4168,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == PackExpansion; } - static bool classof(const PackExpansionType *T) { - return true; - } }; /// ObjCObjectType - Represents a class type in Objective C. @@ -4263,7 +4278,6 @@ public: return T->getTypeClass() == ObjCObject || T->getTypeClass() == ObjCInterface; } - static bool classof(const ObjCObjectType *) { return true; } }; /// ObjCObjectTypeImpl - A class providing a concrete implementation @@ -4327,7 +4341,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == ObjCInterface; } - static bool classof(const ObjCInterfaceType *) { return true; } // Nonsense to "hide" certain members of ObjCObjectType within this // class. People asking for protocols on an ObjCInterfaceType are @@ -4477,7 +4490,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == ObjCObjectPointer; } - static bool classof(const ObjCObjectPointerType *) { return true; } }; class AtomicType : public Type, public llvm::FoldingSetNode { @@ -4508,7 +4520,6 @@ class AtomicType : public Type, public llvm::FoldingSetNode { 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. diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h index 11a878d..8a04bd8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h @@ -159,8 +159,6 @@ public: return !(LHS == RHS); } - static bool classof(const TypeLoc *TL) { return true; } - private: static void initializeImpl(ASTContext &Context, TypeLoc TL, SourceLocation Loc); @@ -192,7 +190,6 @@ public: static bool classof(const TypeLoc *TL) { return !TL->getType().hasLocalQualifiers(); } - static bool classof(const UnqualTypeLoc *TL) { return true; } }; /// \brief Wrapper of type source information for a type with @@ -237,7 +234,6 @@ public: static bool classof(const TypeLoc *TL) { return TL->getType().hasLocalQualifiers(); } - static bool classof(const QualifiedTypeLoc *TL) { return true; } }; inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { @@ -250,11 +246,11 @@ inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { /// to a particular Type subclass. It is accepted for a single /// TypeLoc class to correspond to multiple Type classes. /// -/// \param Base a class from which to derive -/// \param Derived the class deriving from this one -/// \param TypeClass the concrete Type subclass associated with this +/// \tparam Base a class from which to derive +/// \tparam Derived the class deriving from this one +/// \tparam TypeClass the concrete Type subclass associated with this /// location type -/// \param LocalData the structure type of local location data for +/// \tparam LocalData the structure type of local location data for /// this type /// /// sizeof(LocalData) needs to be a multiple of sizeof(void*) or @@ -303,9 +299,6 @@ public: static bool classof(const UnqualTypeLoc *TL) { return Derived::classofType(TL->getTypePtr()); } - static bool classof(const Derived *TL) { - return true; - } TypeLoc getNextTypeLoc() const { return getNextTypeLoc(asDerived()->getInnerType()); @@ -380,9 +373,6 @@ public: static bool classof(const UnqualTypeLoc *TL) { return Derived::classofType(TL->getTypePtr()); } - static bool classof(const Derived *TL) { - return true; - } const TypeClass *getTypePtr() const { return cast<TypeClass>(Base::getTypePtr()); @@ -417,7 +407,6 @@ public: } static bool classof(const TypeLoc *TL); - static bool classof(const TypeSpecTypeLoc *TL) { return true; } }; @@ -866,6 +855,7 @@ public: void initializeLocal(ASTContext &Context, SourceLocation Loc) { setNameLoc(Loc); + setNameEndLoc(Loc); } }; @@ -1060,6 +1050,8 @@ public: struct FunctionLocInfo { SourceLocation LocalRangeBegin; + SourceLocation LParenLoc; + SourceLocation RParenLoc; SourceLocation LocalRangeEnd; }; @@ -1083,6 +1075,24 @@ public: getLocalData()->LocalRangeEnd = L; } + 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()); + } + ArrayRef<ParmVarDecl *> getParams() const { return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs()); } @@ -1110,6 +1120,8 @@ public: void initializeLocal(ASTContext &Context, SourceLocation Loc) { setLocalRangeBegin(Loc); + setLParenLoc(Loc); + setRParenLoc(Loc); setLocalRangeEnd(Loc); for (unsigned i = 0, e = getNumArgs(); i != e; ++i) setArg(i, NULL); diff --git a/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h index 0918dc4..9f11ee5 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h +++ b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h @@ -94,7 +94,7 @@ class UnresolvedSetImpl { private: template <unsigned N> friend class UnresolvedSet; UnresolvedSetImpl() {} - UnresolvedSetImpl(const UnresolvedSetImpl &) {} + UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION; public: // We don't currently support assignment through this iterator, so we might diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h index 392dad9..a6aa40b 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h @@ -147,9 +147,10 @@ private: assert((ComponentKind == CK_VCallOffset || ComponentKind == CK_VBaseOffset || ComponentKind == CK_OffsetToTop) && "Invalid component kind!"); - assert(Offset.getQuantity() <= ((1LL << 56) - 1) && "Offset is too big!"); + assert(Offset.getQuantity() < (1LL << 56) && "Offset is too big!"); + assert(Offset.getQuantity() >= -(1LL << 56) && "Offset is too small!"); - Value = ((Offset.getQuantity() << 3) | ComponentKind); + Value = (uint64_t(Offset.getQuantity()) << 3) | ComponentKind; } VTableComponent(Kind ComponentKind, uintptr_t Ptr) { diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h index dd237ee..30b4050 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h @@ -85,7 +85,14 @@ public: class MatchCallback { public: virtual ~MatchCallback(); + + /// \brief Called on every match by the \c MatchFinder. virtual void run(const MatchResult &Result) = 0; + + /// \brief Called at the start of each translation unit. + /// + /// Optionally override to do per translation unit tasks. + virtual void onStartOfTranslationUnit() {} }; /// \brief Called when parsing is finished. Intended for testing only. @@ -112,11 +119,24 @@ public: MatchCallback *Action); void addMatcher(const StatementMatcher &NodeMatch, MatchCallback *Action); + void addMatcher(const NestedNameSpecifierMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const TypeLocMatcher &NodeMatch, + MatchCallback *Action); /// @} /// \brief Creates a clang ASTConsumer that finds all matches. clang::ASTConsumer *newASTConsumer(); + /// \brief Finds all matches on the given \c Node. + /// + /// @{ + void findAll(const Decl &Node, ASTContext &Context); + void findAll(const Stmt &Node, ASTContext &Context); + /// @} + /// \brief Registers a callback to notify the end of parsing. /// /// The provided closure is called after parsing is done, before the AST is @@ -125,11 +145,10 @@ public: void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone); private: - /// \brief The MatchCallback*'s will be called every time the - /// UntypedBaseMatcher matches on the AST. - std::vector< std::pair< - const internal::UntypedBaseMatcher*, - MatchCallback*> > Triggers; + /// \brief For each \c DynTypedMatcher a \c MatchCallback that will be called + /// when it matches. + std::vector<std::pair<const internal::DynTypedMatcher*, MatchCallback*> > + MatcherCallbackPairs; /// \brief Called when parsing is done. ParsingDoneTestCallback *ParsingDone; diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h index 33ef3dc..a70dd5c 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -14,7 +14,7 @@ // a functional in-language DSL to express queries over the C++ AST. // // For example, to match a class with a certain name, one would call: -// record(hasName("MyClass")) +// recordDecl(hasName("MyClass")) // which returns a matcher that can be used to find all AST nodes that declare // a class named 'MyClass'. // @@ -25,7 +25,7 @@ // // For example, when we're interested in child classes of a certain class, we // would write: -// record(hasName("MyClass"), hasChild(id("child", record()))) +// recordDecl(hasName("MyClass"), hasChild(id("child", recordDecl()))) // When the match is found via the MatchFinder, a user provided callback will // be called with a BoundNodes instance that contains a mapping from the // strings that we provided for the id(...) calls to the nodes that were @@ -57,52 +57,47 @@ namespace ast_matchers { /// \brief Maps string IDs to AST nodes matched by parts of a matcher. /// -/// The bound nodes are generated by adding id(...) matchers into the -/// match expression around the matchers for the nodes we want to access later. +/// The bound nodes are generated by calling \c bind("id") on the node matchers +/// of the nodes we want to access later. /// -/// The instances of BoundNodes are created by MatchFinder when the user's +/// The instances of BoundNodes are created by \c MatchFinder when the user's /// callbacks are executed every time a match is found. class BoundNodes { public: - /// \brief Returns the AST node bound to 'ID'. - /// Returns NULL if there was no node bound to 'ID' or if there is a node but + /// \brief Returns the AST node bound to \c ID. + /// + /// Returns NULL if there was no node bound to \c ID or if there is a node but /// it cannot be converted to the specified type. - /// FIXME: We'll need one of those for every base type. + template <typename T> + const T *getNodeAs(StringRef ID) const { + return MyBoundNodes.getNodeAs<T>(ID); + } + + /// \brief Deprecated. Please use \c getNodeAs instead. /// @{ template <typename T> const T *getDeclAs(StringRef ID) const { - return getNodeAs<T>(DeclBindings, ID); + return getNodeAs<T>(ID); } template <typename T> const T *getStmtAs(StringRef ID) const { - return getNodeAs<T>(StmtBindings, ID); + return getNodeAs<T>(ID); } /// @} private: /// \brief Create BoundNodes from a pre-filled map of bindings. - BoundNodes(const std::map<std::string, const Decl*> &DeclBindings, - const std::map<std::string, const Stmt*> &StmtBindings) - : DeclBindings(DeclBindings), StmtBindings(StmtBindings) {} - - template <typename T, typename MapT> - const T *getNodeAs(const MapT &Bindings, StringRef ID) const { - typename MapT::const_iterator It = Bindings.find(ID); - if (It == Bindings.end()) { - return NULL; - } - return llvm::dyn_cast<T>(It->second); - } + BoundNodes(internal::BoundNodesMap &MyBoundNodes) + : MyBoundNodes(MyBoundNodes) {} - std::map<std::string, const Decl*> DeclBindings; - std::map<std::string, const Stmt*> StmtBindings; + internal::BoundNodesMap MyBoundNodes; friend class internal::BoundNodesTree; }; -/// \brief If the provided matcher matches a node, binds the node to 'ID'. +/// \brief If the provided matcher matches a node, binds the node to \c ID. /// -/// FIXME: Add example for accessing it. +/// FIXME: Do we want to support this now that we have bind()? template <typename T> internal::Matcher<T> id(const std::string &ID, const internal::BindableMatcher<T> &InnerMatcher) { @@ -113,20 +108,27 @@ internal::Matcher<T> id(const std::string &ID, /// hierarchy. /// @{ typedef internal::Matcher<Decl> DeclarationMatcher; -typedef internal::Matcher<QualType> TypeMatcher; typedef internal::Matcher<Stmt> StatementMatcher; +typedef internal::Matcher<QualType> TypeMatcher; +typedef internal::Matcher<TypeLoc> TypeLocMatcher; +typedef internal::Matcher<NestedNameSpecifier> NestedNameSpecifierMatcher; +typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher; /// @} /// \brief Matches any node. /// /// Useful when another matcher requires a child matcher, but there's no /// additional constraint. This will often be used with an explicit conversion -/// to a internal::Matcher<> type such as TypeMatcher. +/// to an \c internal::Matcher<> type such as \c TypeMatcher. /// -/// Example: DeclarationMatcher(anything()) matches all declarations, e.g., +/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g., +/// \code /// "int* p" and "void f()" in /// int* p; /// void f(); +/// \endcode +/// +/// Usable as: Any Matcher inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher> anything() { return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>(); } @@ -144,53 +146,69 @@ const internal::VariadicDynCastAllOfMatcher<Decl, Decl> decl; /// \brief Matches a declaration of anything that could have a name. /// -/// Example matches X, S, the anonymous union type, i, and U; +/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U; +/// \code /// typedef int X; /// struct S { /// union { /// int i; /// } U; /// }; -const internal::VariadicDynCastAllOfMatcher< - Decl, - NamedDecl> nameableDeclaration; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl; /// \brief Matches C++ class declarations. /// -/// Example matches X, Z +/// Example matches \c X, \c Z +/// \code /// class X; /// template<class T> class Z {}; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, - CXXRecordDecl> record; + CXXRecordDecl> recordDecl; + +/// \brief Matches C++ class template declarations. +/// +/// Example matches \c Z +/// \code +/// template<class T> class Z {}; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Decl, + ClassTemplateDecl> classTemplateDecl; /// \brief Matches C++ class template specializations. /// /// Given +/// \code /// template<typename T> class A {}; /// template<> class A<double> {}; /// A<int> a; -/// classTemplateSpecialization() +/// \endcode +/// classTemplateSpecializationDecl() /// matches the specializations \c A<int> and \c A<double> const internal::VariadicDynCastAllOfMatcher< Decl, - ClassTemplateSpecializationDecl> classTemplateSpecialization; + ClassTemplateSpecializationDecl> classTemplateSpecializationDecl; /// \brief Matches classTemplateSpecializations that have at least one -/// TemplateArgument matching the given Matcher. +/// TemplateArgument matching the given InnerMatcher. /// /// Given +/// \code /// template<typename T> class A {}; /// template<> class A<double> {}; /// A<int> a; -/// classTemplateSpecialization(hasAnyTemplateArgument( +/// \endcode +/// classTemplateSpecializationDecl(hasAnyTemplateArgument( /// refersToType(asString("int")))) /// matches the specialization \c A<int> AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument, - internal::Matcher<TemplateArgument>, Matcher) { + internal::Matcher<TemplateArgument>, InnerMatcher) { const TemplateArgumentList &List = Node.getTemplateArgs(); for (unsigned i = 0; i < List.size(); ++i) { - if (Matcher.matches(List.get(i), Finder, Builder)) + if (InnerMatcher.matches(List.get(i), Finder, Builder)) return true; } return false; @@ -201,19 +219,25 @@ AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument, /// /// Parentheses and explicit casts are not discarded. /// Given +/// \code /// int arr[5]; /// int a = 0; /// char b = 0; /// const int c = a; /// int *d = arr; /// long e = (long) 0l; +/// \endcode /// The matchers -/// variable(hasInitializer(ignoringImpCasts(integerLiteral()))) -/// variable(hasInitializer(ignoringImpCasts(declarationReference()))) +/// \code +/// varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))) +/// varDecl(hasInitializer(ignoringImpCasts(declRefExpr()))) +/// \endcode /// would match the declarations for a, b, c, and d, but not e. -/// while -/// variable(hasInitializer(integerLiteral())) -/// variable(hasInitializer(declarationReference())) +/// While +/// \code +/// varDecl(hasInitializer(integerLiteral())) +/// varDecl(hasInitializer(declRefExpr())) +/// \endcode /// only match the declarations for b, c, and d. AST_MATCHER_P(Expr, ignoringImpCasts, internal::Matcher<Expr>, InnerMatcher) { @@ -225,15 +249,17 @@ AST_MATCHER_P(Expr, ignoringImpCasts, /// /// Implicit and non-C Style casts are also discarded. /// Given +/// \code /// int a = 0; /// char b = (0); /// void* c = reinterpret_cast<char*>(0); /// char d = char(0); +/// \endcode /// The matcher -/// variable(hasInitializer(ignoringParenCasts(integerLiteral()))) +/// varDecl(hasInitializer(ignoringParenCasts(integerLiteral()))) /// would match the declarations for a, b, c, and d. /// while -/// variable(hasInitializer(integerLiteral())) +/// varDecl(hasInitializer(integerLiteral())) /// only match the declaration for a. AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher) { return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder); @@ -244,21 +270,21 @@ AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher) { /// /// Explicit casts are not discarded. /// Given +/// \code /// int arr[5]; /// int a = 0; /// char b = (0); /// const int c = a; /// int *d = (arr); /// long e = ((long) 0l); +/// \endcode /// The matchers -/// variable(hasInitializer(ignoringParenImpCasts( -/// integerLiteral()))) -/// variable(hasInitializer(ignoringParenImpCasts( -/// declarationReference()))) +/// varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral()))) +/// varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr()))) /// would match the declarations for a, b, c, and d, but not e. /// while -/// variable(hasInitializer(integerLiteral())) -/// variable(hasInitializer(declarationReference())) +/// varDecl(hasInitializer(integerLiteral())) +/// varDecl(hasInitializer(declRefExpr())) /// would only match the declaration for a. AST_MATCHER_P(Expr, ignoringParenImpCasts, internal::Matcher<Expr>, InnerMatcher) { @@ -266,101 +292,119 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts, } /// \brief Matches classTemplateSpecializations where the n'th TemplateArgument -/// matches the given Matcher. +/// matches the given InnerMatcher. /// /// Given +/// \code /// template<typename T, typename U> class A {}; /// A<bool, int> b; /// A<int, bool> c; -/// classTemplateSpecialization(hasTemplateArgument( +/// \endcode +/// classTemplateSpecializationDecl(hasTemplateArgument( /// 1, refersToType(asString("int")))) /// matches the specialization \c A<bool, int> AST_MATCHER_P2(ClassTemplateSpecializationDecl, hasTemplateArgument, - unsigned, N, internal::Matcher<TemplateArgument>, Matcher) { + unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) { const TemplateArgumentList &List = Node.getTemplateArgs(); if (List.size() <= N) return false; - return Matcher.matches(List.get(N), Finder, Builder); + return InnerMatcher.matches(List.get(N), Finder, Builder); } /// \brief Matches a TemplateArgument that refers to a certain type. /// /// Given +/// \code /// struct X {}; /// template<typename T> struct A {}; /// A<X> a; -/// classTemplateSpecialization(hasAnyTemplateArgument( +/// \endcode +/// classTemplateSpecializationDecl(hasAnyTemplateArgument( /// refersToType(class(hasName("X"))))) /// matches the specialization \c A<X> AST_MATCHER_P(TemplateArgument, refersToType, - internal::Matcher<QualType>, Matcher) { + internal::Matcher<QualType>, InnerMatcher) { if (Node.getKind() != TemplateArgument::Type) return false; - return Matcher.matches(Node.getAsType(), Finder, Builder); + return InnerMatcher.matches(Node.getAsType(), Finder, Builder); } /// \brief Matches a TemplateArgument that refers to a certain declaration. /// /// Given +/// \code /// template<typename T> struct A {}; /// struct B { B* next; }; /// A<&B::next> a; -/// classTemplateSpecialization(hasAnyTemplateArgument( -/// refersToDeclaration(field(hasName("next")))) -/// matches the specialization \c A<&B::next> with \c field(...) matching +/// \endcode +/// classTemplateSpecializationDecl(hasAnyTemplateArgument( +/// refersToDeclaration(fieldDecl(hasName("next")))) +/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching /// \c B::next AST_MATCHER_P(TemplateArgument, refersToDeclaration, - internal::Matcher<Decl>, Matcher) { - if (const Decl *Declaration = Node.getAsDecl()) - return Matcher.matches(*Declaration, Finder, Builder); + internal::Matcher<Decl>, InnerMatcher) { + if (Node.getKind() == TemplateArgument::Declaration) + return InnerMatcher.matches(*Node.getAsDecl(), Finder, Builder); return false; } /// \brief Matches C++ constructor declarations. /// /// Example matches Foo::Foo() and Foo::Foo(int) +/// \code /// class Foo { /// public: /// Foo(); /// Foo(int); /// int DoSomething(); /// }; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, - CXXConstructorDecl> constructor; + CXXConstructorDecl> constructorDecl; /// \brief Matches explicit C++ destructor declarations. /// /// Example matches Foo::~Foo() +/// \code /// class Foo { /// public: /// virtual ~Foo(); /// }; -const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl> destructor; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Decl, + CXXDestructorDecl> destructorDecl; /// \brief Matches enum declarations. /// /// Example matches X +/// \code /// enum X { /// A, B, C /// }; +/// \endcode const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl; /// \brief Matches enum constants. /// /// Example matches A, B, C +/// \code /// enum X { /// A, B, C /// }; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, - EnumConstantDecl> enumConstant; + EnumConstantDecl> enumConstantDecl; /// \brief Matches method declarations. /// /// Example matches y +/// \code /// class X { void y() }; -const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> method; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> methodDecl; /// \brief Matches variable declarations. /// @@ -368,76 +412,111 @@ const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> method; /// "field" declarations in Clang parlance. /// /// Example matches a +/// \code /// int a; -const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> variable; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl; /// \brief Matches field declarations. /// /// Given +/// \code /// class X { int m; }; -/// field() +/// \endcode +/// fieldDecl() /// matches 'm'. -const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> field; +const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl; /// \brief Matches function declarations. /// /// Example matches f +/// \code /// void f(); -const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> function; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl; +/// \brief Matches C++ function template declarations. +/// +/// Example matches f +/// \code +/// template<class T> void f(T t) {} +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Decl, + FunctionTemplateDecl> functionTemplateDecl; /// \brief Matches statements. /// /// Given +/// \code /// { ++a; } -/// statement() +/// \endcode +/// stmt() /// matches both the compound statement '{ ++a; }' and '++a'. -const internal::VariadicDynCastAllOfMatcher<Stmt, Stmt> statement; +const internal::VariadicDynCastAllOfMatcher<Stmt, Stmt> stmt; /// \brief Matches declaration statements. /// /// Given +/// \code /// int a; -/// declarationStatement() +/// \endcode +/// declStmt() /// matches 'int a'. const internal::VariadicDynCastAllOfMatcher< Stmt, - DeclStmt> declarationStatement; + DeclStmt> declStmt; /// \brief Matches member expressions. /// /// Given +/// \code /// class Y { /// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; } /// int a; static int b; /// }; -/// memberExpression() +/// \endcode +/// memberExpr() /// matches this->x, x, y.x, a, this->b -const internal::VariadicDynCastAllOfMatcher< - Stmt, - MemberExpr> memberExpression; +const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr; /// \brief Matches call expressions. /// /// Example matches x.y() and y() +/// \code /// X x; /// x.y(); /// y(); -const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> call; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr; + +/// \brief Matches lambda expressions. +/// +/// Example matches [&](){return 5;} +/// \code +/// [&](){return 5;} +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr; /// \brief Matches member call expressions. /// /// Example matches x.y() +/// \code /// X x; /// x.y(); -const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr> memberCall; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CXXMemberCallExpr> memberCallExpr; /// \brief Matches init list expressions. /// /// Given +/// \code /// int a[] = { 1, 2 }; /// struct B { int x, y; }; /// B b = { 5, 6 }; +/// \endcode /// initList() /// matches "{ 1, 2 }" and "{ 5, 6 }" const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr; @@ -445,8 +524,10 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr; /// \brief Matches using declarations. /// /// Given +/// \code /// namespace X { int x; } /// using X::x; +/// \endcode /// usingDecl() /// matches \code using X::x \endcode const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl; @@ -454,49 +535,89 @@ const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl; /// \brief Matches constructor call expressions (including implicit ones). /// /// Example matches string(ptr, n) and ptr within arguments of f -/// (matcher = constructorCall()) +/// (matcher = constructExpr()) +/// \code /// void f(const string &a, const string &b); /// char *ptr; /// int n; /// f(string(ptr, n), ptr); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXConstructExpr> constructorCall; + CXXConstructExpr> constructExpr; + +/// \brief Matches implicit and explicit this expressions. +/// +/// Example matches the implicit this expression in "return i". +/// (matcher = thisExpr()) +/// \code +/// struct foo { +/// int i; +/// int f() { return i; } +/// }; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> thisExpr; /// \brief Matches nodes where temporaries are created. /// /// Example matches FunctionTakesString(GetStringByValue()) -/// (matcher = bindTemporaryExpression()) +/// (matcher = bindTemporaryExpr()) +/// \code /// FunctionTakesString(GetStringByValue()); /// FunctionTakesStringByPointer(GetStringPointer()); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXBindTemporaryExpr> bindTemporaryExpression; + CXXBindTemporaryExpr> bindTemporaryExpr; + +/// \brief Matches nodes where temporaries are materialized. +/// +/// Example: Given +/// \code +/// struct T {void func()}; +/// T f(); +/// void g(T); +/// \endcode +/// materializeTemporaryExpr() matches 'f()' in these statements +/// \code +/// T u(f()); +/// g(f()); +/// \endcode +/// but does not match +/// \code +/// f(); +/// f().func(); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + MaterializeTemporaryExpr> materializeTemporaryExpr; /// \brief Matches new expressions. /// /// Given +/// \code /// new X; -/// newExpression() +/// \endcode +/// newExpr() /// matches 'new X'. -const internal::VariadicDynCastAllOfMatcher< - Stmt, - CXXNewExpr> newExpression; +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> newExpr; /// \brief Matches delete expressions. /// /// Given +/// \code /// delete X; -/// deleteExpression() +/// \endcode +/// deleteExpr() /// matches 'delete X'. -const internal::VariadicDynCastAllOfMatcher< - Stmt, - CXXDeleteExpr> deleteExpression; +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> deleteExpr; /// \brief Matches array subscript expressions. /// /// Given +/// \code /// int i = a[1]; +/// \endcode /// arraySubscriptExpr() /// matches "a[1]" const internal::VariadicDynCastAllOfMatcher< @@ -507,12 +628,14 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example matches the CXXDefaultArgExpr placeholder inserted for the /// default value of the second parameter in the call expression f(42) -/// (matcher = defaultArgument()) +/// (matcher = defaultArgExpr()) +/// \code /// void f(int x, int y = 0); /// f(42); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXDefaultArgExpr> defaultArgument; + CXXDefaultArgExpr> defaultArgExpr; /// \brief Matches overloaded operator calls. /// @@ -522,50 +645,67 @@ const internal::VariadicDynCastAllOfMatcher< /// FIXME: figure out why these do not match? /// /// Example matches both operator<<((o << b), c) and operator<<(o, b) -/// (matcher = overloadedOperatorCall()) +/// (matcher = operatorCallExpr()) +/// \code /// ostream &operator<< (ostream &out, int i) { }; /// ostream &o; int b = 1, c = 1; /// o << b << c; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXOperatorCallExpr> overloadedOperatorCall; + CXXOperatorCallExpr> operatorCallExpr; /// \brief Matches expressions. /// /// Example matches x() +/// \code /// void f() { x(); } -const internal::VariadicDynCastAllOfMatcher< - Stmt, - Expr> expression; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr; /// \brief Matches expressions that refer to declarations. /// /// Example matches x in if (x) +/// \code /// bool x; /// if (x) {} -const internal::VariadicDynCastAllOfMatcher< - Stmt, - DeclRefExpr> declarationReference; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr; /// \brief Matches if statements. /// /// Example matches 'if (x) {}' +/// \code /// if (x) {} +/// \endcode const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt; /// \brief Matches for statements. /// /// Example matches 'for (;;) {}' +/// \code /// for (;;) {} -const internal::VariadicDynCastAllOfMatcher< - Stmt, ForStmt> forStmt; +/// int i[] = {1, 2, 3}; for (auto a : i); +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt; + +/// \brief Matches range-based for statements. +/// +/// forRangeStmt() matches 'for (auto a : i)' +/// \code +/// int i[] = {1, 2, 3}; for (auto a : i); +/// for(int j = 0; j < 5; ++j); +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt; /// \brief Matches the increment statement of a for loop. /// /// Example: /// forStmt(hasIncrement(unaryOperator(hasOperatorName("++")))) /// matches '++x' in +/// \code /// for (x; x < N; ++x) { } +/// \endcode AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>, InnerMatcher) { const Stmt *const Increment = Node.getInc(); @@ -576,9 +716,11 @@ AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>, /// \brief Matches the initialization statement of a for loop. /// /// Example: -/// forStmt(hasLoopInit(declarationStatement())) +/// forStmt(hasLoopInit(declStmt())) /// matches 'int x = 0' in +/// \code /// for (int x = 0; x < N; ++x) { } +/// \endcode AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>, InnerMatcher) { const Stmt *const Init = Node.getInit(); @@ -588,53 +730,167 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>, /// \brief Matches while statements. /// /// Given +/// \code /// while (true) {} +/// \endcode /// whileStmt() /// matches 'while (true) {}'. -const internal::VariadicDynCastAllOfMatcher< - Stmt, - WhileStmt> whileStmt; +const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt; /// \brief Matches do statements. /// /// Given +/// \code /// do {} while (true); +/// \endcode /// doStmt() /// matches 'do {} while(true)' const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt; +/// \brief Matches break statements. +/// +/// Given +/// \code +/// while (true) { break; } +/// \endcode +/// breakStmt() +/// matches 'break' +const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt; + +/// \brief Matches continue statements. +/// +/// Given +/// \code +/// while (true) { continue; } +/// \endcode +/// continueStmt() +/// matches 'continue' +const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt; + +/// \brief Matches return statements. +/// +/// Given +/// \code +/// return 1; +/// \endcode +/// returnStmt() +/// matches 'return 1' +const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt; + +/// \brief Matches goto statements. +/// +/// Given +/// \code +/// goto FOO; +/// FOO: bar(); +/// \endcode +/// gotoStmt() +/// matches 'goto FOO' +const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt; + +/// \brief Matches label statements. +/// +/// Given +/// \code +/// goto FOO; +/// FOO: bar(); +/// \endcode +/// labelStmt() +/// matches 'FOO:' +const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt; + +/// \brief Matches switch statements. +/// +/// Given +/// \code +/// switch(a) { case 42: break; default: break; } +/// \endcode +/// switchStmt() +/// matches 'switch(a)'. +const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt; + /// \brief Matches case and default statements inside switch statements. /// /// Given +/// \code /// switch(a) { case 42: break; default: break; } +/// \endcode /// switchCase() /// matches 'case 42: break;' and 'default: break;'. -const internal::VariadicDynCastAllOfMatcher< - Stmt, - SwitchCase> switchCase; +const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase; /// \brief Matches compound statements. /// /// Example matches '{}' and '{{}}'in 'for (;;) {{}}' +/// \code /// for (;;) {{}} -const internal::VariadicDynCastAllOfMatcher< - Stmt, - CompoundStmt> compoundStatement; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt; + +/// \brief Matches catch statements. +/// +/// \code +/// try {} catch(int i) {} +/// \endcode +/// catchStmt() +/// matches 'catch(int i)' +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> catchStmt; + +/// \brief Matches try statements. +/// +/// \code +/// try {} catch(int i) {} +/// \endcode +/// tryStmt() +/// matches 'try {}' +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> tryStmt; + +/// \brief Matches throw expressions. +/// +/// \code +/// try { throw 5; } catch(int i) {} +/// \endcode +/// throwExpr() +/// matches 'throw 5' +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> throwExpr; + +/// \brief Matches null statements. +/// +/// \code +/// foo();; +/// \endcode +/// nullStmt() +/// matches the second ';' +const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt; + +/// \brief Matches asm statements. +/// +/// \code +/// int i = 100; +/// __asm("mov al, 2"); +/// \endcode +/// asmStmt() +/// matches '__asm("mov al, 2")' +const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt; /// \brief Matches bool literals. /// /// Example matches true +/// \code /// true +/// \endcode const internal::VariadicDynCastAllOfMatcher< - Expr, + Stmt, CXXBoolLiteralExpr> boolLiteral; /// \brief Matches string literals (also matches wide string literals). /// /// Example matches "abcd", L"abcd" +/// \code /// char *s = "abcd"; wchar_t *ws = L"abcd" +/// \endcode const internal::VariadicDynCastAllOfMatcher< - Expr, + Stmt, StringLiteral> stringLiteral; /// \brief Matches character literals (also matches wchar_t). @@ -643,9 +899,11 @@ const internal::VariadicDynCastAllOfMatcher< /// though. /// /// Example matches 'a', L'a' +/// \code /// char ch = 'a'; wchar_t chw = L'a'; +/// \endcode const internal::VariadicDynCastAllOfMatcher< - Expr, + Stmt, CharacterLiteral> characterLiteral; /// \brief Matches integer literals of all sizes / encodings. @@ -654,13 +912,27 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example matches 1, 1L, 0x1, 1U const internal::VariadicDynCastAllOfMatcher< - Expr, + Stmt, IntegerLiteral> integerLiteral; +/// \brief Matches user defined literal operator call. +/// +/// Example match: "foo"_suffix +const internal::VariadicDynCastAllOfMatcher< + Stmt, + UserDefinedLiteral> userDefinedLiteral; + +/// \brief Matches nullptr literal. +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CXXNullPtrLiteralExpr> nullPtrLiteralExpr; + /// \brief Matches binary operator expressions. /// /// Example matches a || b +/// \code /// !(a || b) +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, BinaryOperator> binaryOperator; @@ -668,7 +940,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches unary operator expressions. /// /// Example matches !a +/// \code /// !a || b +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, UnaryOperator> unaryOperator; @@ -676,7 +950,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches conditional operator expressions. /// /// Example matches a ? b : c +/// \code /// (a ? b : c) + 42 +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, ConditionalOperator> conditionalOperator; @@ -688,10 +964,12 @@ const internal::VariadicDynCastAllOfMatcher< /// more readable. /// /// Example matches reinterpret_cast<char*>(&p) in +/// \code /// void* p = reinterpret_cast<char*>(&p); +/// \endcode const internal::VariadicDynCastAllOfMatcher< - Expr, - CXXReinterpretCastExpr> reinterpretCast; + Stmt, + CXXReinterpretCastExpr> reinterpretCastExpr; /// \brief Matches a C++ static_cast expression. /// @@ -699,38 +977,54 @@ const internal::VariadicDynCastAllOfMatcher< /// \see reinterpretCast /// /// Example: -/// staticCast() +/// staticCastExpr() /// matches /// static_cast<long>(8) /// in +/// \code /// long eight(static_cast<long>(8)); +/// \endcode const internal::VariadicDynCastAllOfMatcher< - Expr, - CXXStaticCastExpr> staticCast; + Stmt, + CXXStaticCastExpr> staticCastExpr; /// \brief Matches a dynamic_cast expression. /// /// Example: -/// dynamicCast() +/// dynamicCastExpr() /// matches /// dynamic_cast<D*>(&b); /// in +/// \code /// struct B { virtual ~B() {} }; struct D : B {}; /// B b; /// D* p = dynamic_cast<D*>(&b); +/// \endcode const internal::VariadicDynCastAllOfMatcher< - Expr, - CXXDynamicCastExpr> dynamicCast; + Stmt, + CXXDynamicCastExpr> dynamicCastExpr; /// \brief Matches a const_cast expression. /// /// Example: Matches const_cast<int*>(&r) in +/// \code /// int n = 42; -/// const int& r(n); +/// const int &r(n); /// int* p = const_cast<int*>(&r); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CXXConstCastExpr> constCastExpr; + +/// \brief Matches a C-style cast expression. +/// +/// Example: Matches (int*) 2.2f in +/// \code +/// int i = (int) 2.2f; +/// \endcode const internal::VariadicDynCastAllOfMatcher< - Expr, - CXXConstCastExpr> constCast; + Stmt, + CStyleCastExpr> cStyleCastExpr; /// \brief Matches explicit cast expressions. /// @@ -746,98 +1040,127 @@ const internal::VariadicDynCastAllOfMatcher< /// \see hasDestinationType. /// /// Example: matches all five of the casts in +/// \code /// int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42))))) +/// \endcode /// but does not match the implicit conversion in +/// \code /// long ell = 42; +/// \endcode const internal::VariadicDynCastAllOfMatcher< - Expr, - ExplicitCastExpr> explicitCast; + Stmt, + ExplicitCastExpr> explicitCastExpr; /// \brief Matches the implicit cast nodes of Clang's AST. /// /// This matches many different places, including function call return value /// eliding, as well as any type conversions. const internal::VariadicDynCastAllOfMatcher< - Expr, - ImplicitCastExpr> implicitCast; + Stmt, + ImplicitCastExpr> implicitCastExpr; /// \brief Matches any cast nodes of Clang's AST. /// /// Example: castExpr() matches each of the following: +/// \code /// (int) 3; /// const_cast<Expr *>(SubExpr); /// char c = 0; +/// \endcode /// but does not match +/// \code /// int i = (0); /// int k = 0; -const internal::VariadicDynCastAllOfMatcher< - Expr, - CastExpr> castExpr; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr; /// \brief Matches functional cast expressions /// /// Example: Matches Foo(bar); +/// \code /// Foo f = bar; /// Foo g = (Foo) bar; /// Foo h = Foo(bar); +/// \endcode const internal::VariadicDynCastAllOfMatcher< - Expr, - CXXFunctionalCastExpr> functionalCast; + Stmt, + CXXFunctionalCastExpr> functionalCastExpr; + +/// \brief Matches \c QualTypes in the clang AST. +const internal::VariadicAllOfMatcher<QualType> qualType; + +/// \brief Matches \c Types in the clang AST. +const internal::VariadicDynCastAllOfMatcher<Type, Type> type; + +/// \brief Matches \c TypeLocs in the clang AST. +const internal::VariadicDynCastAllOfMatcher<TypeLoc, TypeLoc> typeLoc; /// \brief Various overloads for the anyOf matcher. /// @{ -template<typename C1, typename C2> -internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, C2> -anyOf(const C1 &P1, const C2 &P2) { + +/// \brief Matches if any of the given matchers matches. +/// +/// Usable as: Any Matcher +template<typename M1, typename M2> +internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1, M2> +anyOf(const M1 &P1, const M2 &P2) { return internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, - C1, C2 >(P1, P2); + M1, M2 >(P1, P2); } -template<typename C1, typename C2, typename C3> -internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, - internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2, C3> > -anyOf(const C1 &P1, const C2 &P2, const C3 &P3) { +template<typename M1, typename M2, typename M3> +internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2, M3> > +anyOf(const M1 &P1, const M2 &P2, const M3 &P3) { return anyOf(P1, anyOf(P2, P3)); } -template<typename C1, typename C2, typename C3, typename C4> -internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, - internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2, +template<typename M1, typename M2, typename M3, typename M4> +internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2, internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, - C3, C4> > > -anyOf(const C1 &P1, const C2 &P2, const C3 &P3, const C4 &P4) { + M3, M4> > > +anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) { return anyOf(P1, anyOf(P2, anyOf(P3, P4))); } -template<typename C1, typename C2, typename C3, typename C4, typename C5> -internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, - internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2, - internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C3, +template<typename M1, typename M2, typename M3, typename M4, typename M5> +internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M3, internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, - C4, C5> > > > -anyOf(const C1& P1, const C2& P2, const C3& P3, const C4& P4, const C5& P5) { + M4, M5> > > > +anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) { return anyOf(P1, anyOf(P2, anyOf(P3, anyOf(P4, P5)))); } + /// @} /// \brief Various overloads for the allOf matcher. /// @{ -template<typename C1, typename C2> -internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1, C2> -allOf(const C1 &P1, const C2 &P2) { + +/// \brief Matches if all given matchers match. +/// +/// Usable as: Any Matcher +template<typename M1, typename M2> +internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1, M2> +allOf(const M1 &P1, const M2 &P2) { return internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, - C1, C2>(P1, P2); + M1, M2>(P1, P2); } -template<typename C1, typename C2, typename C3> -internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1, - internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C2, C3> > -allOf(const C1& P1, const C2& P2, const C3& P3) { +template<typename M1, typename M2, typename M3> +internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1, + internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M2, M3> > +allOf(const M1 &P1, const M2 &P2, const M3 &P3) { return allOf(P1, allOf(P2, P3)); } + /// @} /// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) /// /// Given +/// \code /// Foo x = bar; /// int y = sizeof(x) + alignof(x); +/// \endcode /// unaryExprOrTypeTraitExpr() /// matches \c sizeof(x) and \c alignof(x) const internal::VariadicDynCastAllOfMatcher< @@ -847,20 +1170,24 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches unary expressions that have a specific type of argument. /// /// Given +/// \code /// int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c); +/// \endcode /// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int")) /// matches \c sizeof(a) and \c alignof(c) AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType, - internal::Matcher<QualType>, Matcher) { + internal::Matcher<QualType>, InnerMatcher) { const QualType ArgumentType = Node.getTypeOfArgument(); - return Matcher.matches(ArgumentType, Finder, Builder); + return InnerMatcher.matches(ArgumentType, Finder, Builder); } /// \brief Matches unary expressions of a certain kind. /// /// Given +/// \code /// int x; /// int s = sizeof(x) + alignof(x) +/// \endcode /// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf)) /// matches \c sizeof(x) AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) { @@ -870,17 +1197,17 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) { /// \brief Same as unaryExprOrTypeTraitExpr, but only matching /// alignof. inline internal::Matcher<Stmt> alignOfExpr( - const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) { + const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) { return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf( - ofKind(UETT_AlignOf), Matcher))); + ofKind(UETT_AlignOf), InnerMatcher))); } /// \brief Same as unaryExprOrTypeTraitExpr, but only matching /// sizeof. inline internal::Matcher<Stmt> sizeOfExpr( - const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) { + const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) { return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf( - ofKind(UETT_SizeOf), Matcher))); + ofKind(UETT_SizeOf), InnerMatcher))); } /// \brief Matches NamedDecl nodes that have the specified name. @@ -890,10 +1217,14 @@ inline internal::Matcher<Stmt> sizeOfExpr( /// Does not match typedefs of an underlying type with the given name. /// /// Example matches X (Name == "X") +/// \code /// class X; +/// \endcode /// /// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X") -/// namespace a { namespace b { class X; } } +/// \code +/// namespace a { namespace b { class X; } } +/// \endcode AST_MATCHER_P(NamedDecl, hasName, std::string, Name) { assert(!Name.empty()); const std::string FullNameString = "::" + Node.getQualifiedNameAsString(); @@ -914,10 +1245,14 @@ AST_MATCHER_P(NamedDecl, hasName, std::string, Name) { /// of an underlying type with the given name. /// /// Example matches X (regexp == "::X") +/// \code /// class X; +/// \endcode /// /// Example matches X (regexp is one of "::X", "^foo::.*X", among others) -/// namespace foo { namespace bar { class X; } } +/// \code +/// namespace foo { namespace bar { class X; } } +/// \endcode AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { assert(!RegExp.empty()); std::string FullNameString = "::" + Node.getQualifiedNameAsString(); @@ -931,10 +1266,12 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { /// "operator" prefix, such as "<<", for OverloadedOperatorCall's. /// /// Example matches a << b -/// (matcher == overloadedOperatorCall(hasOverloadedOperatorName("<<"))) +/// (matcher == operatorCallExpr(hasOverloadedOperatorName("<<"))) +/// \code /// a << b; /// c && d; // assuming both operator<< /// // and operator&& are overloaded somewhere. +/// \endcode AST_MATCHER_P(CXXOperatorCallExpr, hasOverloadedOperatorName, std::string, Name) { return getOperatorSpelling(Node.getOperator()) == Name; @@ -943,20 +1280,24 @@ AST_MATCHER_P(CXXOperatorCallExpr, /// \brief Matches C++ classes that are directly or indirectly derived from /// a class matching \c Base. /// -/// Note that a class is considered to be also derived from itself. +/// Note that a class is not considered to be derived from itself. /// -/// Example matches X, Y, Z, C (Base == hasName("X")) -/// class X; // A class is considered to be derived from itself +/// Example matches Y, Z, C (Base == hasName("X")) +/// \code +/// class X; /// class Y : public X {}; // directly derived /// class Z : public Y {}; // indirectly derived /// typedef X A; /// typedef A B; /// class C : public B {}; // derived from a typedef of X +/// \endcode /// /// In the following example, Bar matches isDerivedFrom(hasName("X")): +/// \code /// class Foo; /// typedef Foo X; /// class Bar : public Foo {}; // derived from a type that X is a typedef of +/// \endcode AST_MATCHER_P(CXXRecordDecl, isDerivedFrom, internal::Matcher<NamedDecl>, Base) { return Finder->classIsDerivedFrom(&Node, Base, Builder); @@ -968,15 +1309,34 @@ inline internal::Matcher<CXXRecordDecl> isDerivedFrom(StringRef BaseName) { return isDerivedFrom(hasName(BaseName)); } +/// \brief Similar to \c isDerivedFrom(), but also matches classes that directly +/// match \c Base. +inline internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom( + internal::Matcher<NamedDecl> Base) { + return anyOf(Base, isDerivedFrom(Base)); +} + +/// \brief Overloaded method as shortcut for +/// \c isSameOrDerivedFrom(hasName(...)). +inline internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom( + StringRef BaseName) { + assert(!BaseName.empty()); + return isSameOrDerivedFrom(hasName(BaseName)); +} + /// \brief Matches AST nodes that have child AST nodes that match the /// provided matcher. /// -/// Example matches X, Y (matcher = record(has(record(hasName("X"))) +/// Example matches X, Y (matcher = recordDecl(has(recordDecl(hasName("X"))) +/// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class Y { class X {}; }; /// class Z { class Y { class X {}; }; }; // Does not match Z. +/// \endcode /// /// ChildT must be an AST base type. +/// +/// Usable as: Any Matcher template <typename ChildT> internal::ArgumentAdaptingMatcher<internal::HasMatcher, ChildT> has( const internal::Matcher<ChildT> &ChildMatcher) { @@ -988,12 +1348,16 @@ internal::ArgumentAdaptingMatcher<internal::HasMatcher, ChildT> has( /// provided matcher. /// /// Example matches X, Y, Z -/// (matcher = record(hasDescendant(record(hasName("X"))))) +/// (matcher = recordDecl(hasDescendant(recordDecl(hasName("X"))))) +/// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class Y { class X {}; }; /// class Z { class Y { class X {}; }; }; +/// \endcode /// /// DescendantT must be an AST base type. +/// +/// Usable as: Any Matcher template <typename DescendantT> internal::ArgumentAdaptingMatcher<internal::HasDescendantMatcher, DescendantT> hasDescendant(const internal::Matcher<DescendantT> &DescendantMatcher) { @@ -1002,22 +1366,25 @@ hasDescendant(const internal::Matcher<DescendantT> &DescendantMatcher) { DescendantT>(DescendantMatcher); } - /// \brief Matches AST nodes that have child AST nodes that match the /// provided matcher. /// -/// Example matches X, Y (matcher = record(forEach(record(hasName("X"))) +/// Example matches X, Y (matcher = recordDecl(forEach(recordDecl(hasName("X"))) +/// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class Y { class X {}; }; /// class Z { class Y { class X {}; }; }; // Does not match Z. +/// \endcode /// /// ChildT must be an AST base type. /// /// As opposed to 'has', 'forEach' will cause a match for each result that /// matches instead of only on the first one. +/// +/// Usable as: Any Matcher template <typename ChildT> internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach( - const internal::Matcher<ChildT>& ChildMatcher) { + const internal::Matcher<ChildT> &ChildMatcher) { return internal::ArgumentAdaptingMatcher< internal::ForEachMatcher, ChildT>(ChildMatcher); @@ -1027,10 +1394,12 @@ internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach( /// provided matcher. /// /// Example matches X, A, B, C -/// (matcher = record(forEachDescendant(record(hasName("X"))))) +/// (matcher = recordDecl(forEachDescendant(recordDecl(hasName("X"))))) +/// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class A { class X {}; }; /// class B { class C { class X {}; }; }; +/// \endcode /// /// DescendantT must be an AST base type. /// @@ -1038,25 +1407,72 @@ internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach( /// each result that matches instead of only on the first one. /// /// Note: Recursively combined ForEachDescendant can cause many matches: -/// record(forEachDescendant(record(forEachDescendant(record())))) +/// recordDecl(forEachDescendant(recordDecl(forEachDescendant(recordDecl())))) /// will match 10 times (plus injected class name matches) on: +/// \code /// class A { class B { class C { class D { class E {}; }; }; }; }; +/// \endcode +/// +/// Usable as: Any Matcher template <typename DescendantT> -internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher, DescendantT> +internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher, + DescendantT> forEachDescendant( - const internal::Matcher<DescendantT>& DescendantMatcher) { + const internal::Matcher<DescendantT> &DescendantMatcher) { return internal::ArgumentAdaptingMatcher< internal::ForEachDescendantMatcher, DescendantT>(DescendantMatcher); } +/// \brief Matches AST nodes that have a parent that matches the provided +/// matcher. +/// +/// Given +/// \code +/// void f() { for (;;) { int x = 42; if (true) { int x = 43; } } } +/// \endcode +/// \c compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }". +/// +/// Usable as: Any Matcher +template <typename ParentT> +internal::ArgumentAdaptingMatcher<internal::HasParentMatcher, ParentT> +hasParent(const internal::Matcher<ParentT> &ParentMatcher) { + return internal::ArgumentAdaptingMatcher< + internal::HasParentMatcher, + ParentT>(ParentMatcher); +} + +/// \brief Matches AST nodes that have an ancestor that matches the provided +/// matcher. +/// +/// Given +/// \code +/// void f() { if (true) { int x = 42; } } +/// void g() { for (;;) { int x = 43; } } +/// \endcode +/// \c expr(integerLiteral(hasAncestor(ifStmt()))) matches \c 42, but not 43. +/// +/// Usable as: Any Matcher +template <typename AncestorT> +internal::ArgumentAdaptingMatcher<internal::HasAncestorMatcher, AncestorT> +hasAncestor(const internal::Matcher<AncestorT> &AncestorMatcher) { + return internal::ArgumentAdaptingMatcher< + internal::HasAncestorMatcher, + AncestorT>(AncestorMatcher); +} + /// \brief Matches if the provided matcher does not match. /// -/// Example matches Y (matcher = record(unless(hasName("X")))) +/// Example matches Y (matcher = recordDecl(unless(hasName("X")))) +/// \code /// class X {}; /// class Y {}; +/// \endcode +/// +/// Usable as: Any Matcher template <typename M> -internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M> unless(const M &InnerMatcher) { +internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M> +unless(const M &InnerMatcher) { return internal::PolymorphicMatcherWithParam1< internal::NotMatcher, M>(InnerMatcher); } @@ -1064,7 +1480,8 @@ internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M> unless(const M & /// \brief Matches a type if the declaration of the type matches the given /// matcher. /// -/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr> +/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, +/// Matcher<MemberExpr> inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher, internal::Matcher<Decl> > hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) { @@ -1075,9 +1492,11 @@ inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher, /// \brief Matches on the implicit object argument of a member call expression. /// -/// Example matches y.x() (matcher = call(on(hasType(record(hasName("Y")))))) +/// Example matches y.x() (matcher = callExpr(on(hasType(recordDecl(hasName("Y")))))) +/// \code /// class Y { public: void x(); }; /// void z() { Y y; y.x(); }", +/// \endcode /// /// FIXME: Overload to allow directly matching types? AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>, @@ -1092,9 +1511,11 @@ AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>, /// \brief Matches if the call expression's callee expression matches. /// /// Given +/// \code /// class Y { void x() { this->x(); x(); Y y; y.x(); } }; /// void f() { f(); } -/// call(callee(expression())) +/// \endcode +/// callExpr(callee(expr())) /// matches this->x(), x(), y.x(), f() /// with callee(...) /// matching this->x, x, y.x, f respectively @@ -1113,9 +1534,11 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>, /// \brief Matches if the call expression's callee's declaration matches the /// given matcher. /// -/// Example matches y.x() (matcher = call(callee(method(hasName("x"))))) +/// Example matches y.x() (matcher = callExpr(callee(methodDecl(hasName("x"))))) +/// \code /// class Y { public: void x(); }; /// void z() { Y y; y.x(); +/// \endcode inline internal::Matcher<CallExpr> callee( const internal::Matcher<Decl> &InnerMatcher) { return internal::Matcher<CallExpr>(hasDeclaration(InnerMatcher)); @@ -1124,12 +1547,12 @@ inline internal::Matcher<CallExpr> callee( /// \brief Matches if the expression's or declaration's type matches a type /// matcher. /// -/// Example matches x (matcher = expression(hasType( -/// hasDeclaration(record(hasName("X")))))) -/// and z (matcher = variable(hasType( -/// hasDeclaration(record(hasName("X")))))) +/// Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) +/// and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +/// \code /// class X {}; /// void y(X &x) { x; X z; } +/// \endcode AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<QualType>, InnerMatcher) { TOOLING_COMPILE_ASSERT((llvm::is_base_of<Expr, NodeType>::value || @@ -1143,14 +1566,16 @@ AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<QualType>, /// /// In case of a value declaration (for example a variable declaration), /// this resolves one layer of indirection. For example, in the value -/// declaration "X x;", record(hasName("X")) matches the declaration of X, -/// while variable(hasType(record(hasName("X")))) matches the declaration +/// declaration "X x;", recordDecl(hasName("X")) matches the declaration of X, +/// while varDecl(hasType(recordDecl(hasName("X")))) matches the declaration /// of x." /// -/// Example matches x (matcher = expression(hasType(record(hasName("X"))))) -/// and z (matcher = variable(hasType(record(hasName("X"))))) +/// Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) +/// and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +/// \code /// class X {}; /// void y(X &x) { x; X z; } +/// \endcode /// /// Usable as: Matcher<Expr>, Matcher<ValueDecl> inline internal::PolymorphicMatcherWithParam1< @@ -1164,9 +1589,11 @@ hasType(const internal::Matcher<Decl> &InnerMatcher) { /// \brief Matches if the matched type is represented by the given string. /// /// Given +/// \code /// class Y { public: void x(); }; /// void z() { Y* y; y->x(); } -/// call(on(hasType(asString("class Y *")))) +/// \endcode +/// callExpr(on(hasType(asString("class Y *")))) /// matches y->x() AST_MATCHER_P(QualType, asString, std::string, Name) { return Name == Node.getAsString(); @@ -1176,9 +1603,11 @@ AST_MATCHER_P(QualType, asString, std::string, Name) { /// matches the specified matcher. /// /// Example matches y->x() -/// (matcher = call(on(hasType(pointsTo(record(hasName("Y"))))))) +/// (matcher = callExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))))) +/// \code /// class Y { public: void x(); }; /// void z() { Y *y; y->x(); } +/// \endcode AST_MATCHER_P( QualType, pointsTo, internal::Matcher<QualType>, InnerMatcher) { @@ -1197,12 +1626,14 @@ inline internal::Matcher<QualType> pointsTo( /// type matches the specified matcher. /// /// Example matches X &x and const X &y -/// (matcher = variable(hasType(references(record(hasName("X")))))) +/// (matcher = varDecl(hasType(references(recordDecl(hasName("X")))))) +/// \code /// class X { /// void a(X b) { /// X &x = b; /// const X &y = b; /// }; +/// \endcode AST_MATCHER_P(QualType, references, internal::Matcher<QualType>, InnerMatcher) { return (!Node.isNull() && Node->isReferenceType() && @@ -1243,9 +1674,11 @@ inline internal::Matcher<CXXMemberCallExpr> thisPointerType( /// specified matcher. /// /// Example matches x in if(x) -/// (matcher = declarationReference(to(variable(hasName("x"))))) +/// (matcher = declRefExpr(to(varDecl(hasName("x"))))) +/// \code /// bool x; /// if (x) {} +/// \endcode AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>, InnerMatcher) { const Decl *DeclNode = Node.getDecl(); @@ -1259,29 +1692,33 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>, /// FIXME: This currently only works for functions. Fix. /// /// Given +/// \code /// namespace a { void f() {} } /// using a::f; /// void g() { /// f(); // Matches this .. /// a::f(); // .. but not this. /// } -/// declarationReference(throughUsingDeclaration(anything())) +/// \endcode +/// declRefExpr(throughUsingDeclaration(anything())) /// matches \c f() AST_MATCHER_P(DeclRefExpr, throughUsingDecl, - internal::Matcher<UsingShadowDecl>, Matcher) { + internal::Matcher<UsingShadowDecl>, InnerMatcher) { const NamedDecl *FoundDecl = Node.getFoundDecl(); if (const UsingShadowDecl *UsingDecl = llvm::dyn_cast<UsingShadowDecl>(FoundDecl)) - return Matcher.matches(*UsingDecl, Finder, Builder); + return InnerMatcher.matches(*UsingDecl, Finder, Builder); return false; } /// \brief Matches the Decl of a DeclStmt which has a single declaration. /// /// Given +/// \code /// int a, b; /// int c; -/// declarationStatement(hasSingleDecl(anything())) +/// \endcode +/// declStmt(hasSingleDecl(anything())) /// matches 'int c;' but not 'int a, b;'. AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) { if (Node.isSingleDecl()) { @@ -1294,9 +1731,11 @@ AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) { /// \brief Matches a variable declaration that has an initializer expression /// that matches the given matcher. /// -/// Example matches x (matcher = variable(hasInitializer(call()))) +/// Example matches x (matcher = varDecl(hasInitializer(callExpr()))) +/// \code /// bool y() { return true; } /// bool x = y(); +/// \endcode AST_MATCHER_P( VarDecl, hasInitializer, internal::Matcher<Expr>, InnerMatcher) { @@ -1308,9 +1747,11 @@ AST_MATCHER_P( /// \brief Checks that a call expression or a constructor call expression has /// a specific number of arguments (including absent default arguments). /// -/// Example matches f(0, 0) (matcher = call(argumentCountIs(2))) +/// Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) +/// \code /// void f(int x, int y); /// f(0, 0); +/// \endcode AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) { TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value || llvm::is_base_of<CXXConstructExpr, @@ -1323,8 +1764,10 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) { /// call expression. /// /// Example matches y in x(y) -/// (matcher = call(hasArgument(0, declarationReference()))) +/// (matcher = callExpr(hasArgument(0, declRefExpr()))) +/// \code /// void x(int) { int y; x(y); } +/// \endcode AST_POLYMORPHIC_MATCHER_P2( hasArgument, unsigned, N, internal::Matcher<Expr>, InnerMatcher) { TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value || @@ -1340,13 +1783,15 @@ AST_POLYMORPHIC_MATCHER_P2( /// declarations. /// /// Example: Given +/// \code /// int a, b; /// int c; /// int d = 2, e; +/// \endcode /// declCountIs(2) /// matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'. AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) { - return std::distance(Node.decl_begin(), Node.decl_end()) == N; + return std::distance(Node.decl_begin(), Node.decl_end()) == (ptrdiff_t)N; } /// \brief Matches the n'th declaration of a declaration statement. @@ -1355,15 +1800,19 @@ AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) { /// breaks up multiple-declaration DeclStmt's into multiple single-declaration /// DeclStmt's. /// Example: Given non-global declarations +/// \code /// int a, b = 0; /// int c; /// int d = 2, e; -/// declarationStatement(containsDeclaration( -/// 0, variable(hasInitializer(anything())))) +/// \endcode +/// declStmt(containsDeclaration( +/// 0, varDecl(hasInitializer(anything())))) /// matches only 'int d = 2, e;', and -/// declarationStatement(containsDeclaration(1, variable())) +/// declStmt(containsDeclaration(1, varDecl())) +/// \code /// matches 'int a, b = 0' as well as 'int d = 2, e;' /// but 'int c;' is not matched. +/// \endcode AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N, internal::Matcher<Decl>, InnerMatcher) { const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end()); @@ -1377,11 +1826,13 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N, /// \brief Matches a constructor initializer. /// /// Given +/// \code /// struct Foo { /// Foo() : foo_(1) { } /// int foo_; /// }; -/// record(has(constructor(hasAnyConstructorInitializer(anything())))) +/// \endcode +/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer(anything())))) /// record matches Foo, hasAnyConstructorInitializer matches foo_(1) AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, internal::Matcher<CXXCtorInitializer>, InnerMatcher) { @@ -1397,11 +1848,13 @@ AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, /// \brief Matches the field declaration of a constructor initializer. /// /// Given +/// \code /// struct Foo { /// Foo() : foo_(1) { } /// int foo_; /// }; -/// record(has(constructor(hasAnyConstructorInitializer( +/// \endcode +/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer( /// forField(hasName("foo_")))))) /// matches Foo /// with forField matching foo_ @@ -1415,11 +1868,13 @@ AST_MATCHER_P(CXXCtorInitializer, forField, /// \brief Matches the initializer expression of a constructor initializer. /// /// Given +/// \code /// struct Foo { /// Foo() : foo_(1) { } /// int foo_; /// }; -/// record(has(constructor(hasAnyConstructorInitializer( +/// \endcode +/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer( /// withInitializer(integerLiteral(equals(1))))))) /// matches Foo /// with withInitializer matching (1) @@ -1434,12 +1889,14 @@ AST_MATCHER_P(CXXCtorInitializer, withInitializer, /// code (as opposed to implicitly added by the compiler). /// /// Given +/// \code /// struct Foo { /// Foo() { } /// Foo(int) : foo_("A") { } /// string foo_; /// }; -/// constructor(hasAnyConstructorInitializer(isWritten())) +/// \endcode +/// constructorDecl(hasAnyConstructorInitializer(isWritten())) /// will match Foo(int), but not Foo() AST_MATCHER(CXXCtorInitializer, isWritten) { return Node.isWritten(); @@ -1455,8 +1912,10 @@ AST_MATCHER(CXXConstructorDecl, isImplicit) { /// expression. /// /// Given +/// \code /// void x(int, int, int) { int y; x(1, y, 42); } -/// call(hasAnyArgument(declarationReference())) +/// \endcode +/// callExpr(hasAnyArgument(declRefExpr())) /// matches x(1, y, 42) /// with hasAnyArgument(...) /// matching y @@ -1478,8 +1937,10 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, internal::Matcher<Expr>, /// \brief Matches the n'th parameter of a function declaration. /// /// Given +/// \code /// class X { void f(int x) {} }; -/// method(hasParameter(0, hasType(variable()))) +/// \endcode +/// methodDecl(hasParameter(0, hasType(varDecl()))) /// matches f(int x) {} /// with hasParameter(...) /// matching int x @@ -1496,8 +1957,10 @@ AST_MATCHER_P2(FunctionDecl, hasParameter, /// Does not match the 'this' parameter of a method. /// /// Given +/// \code /// class X { void f(int x, int y, int z) {} }; -/// method(hasAnyParameter(hasName("y"))) +/// \endcode +/// methodDecl(hasAnyParameter(hasName("y"))) /// matches f(int x, int y, int z) {} /// with hasAnyParameter(...) /// matching int y @@ -1514,20 +1977,25 @@ AST_MATCHER_P(FunctionDecl, hasAnyParameter, /// \brief Matches the return type of a function declaration. /// /// Given: +/// \code /// class X { int f() { return 1; } }; -/// method(returns(asString("int"))) +/// \endcode +/// methodDecl(returns(asString("int"))) /// matches int f() { return 1; } -AST_MATCHER_P(FunctionDecl, returns, internal::Matcher<QualType>, Matcher) { - return Matcher.matches(Node.getResultType(), Finder, Builder); +AST_MATCHER_P(FunctionDecl, returns, + internal::Matcher<QualType>, InnerMatcher) { + return InnerMatcher.matches(Node.getResultType(), Finder, Builder); } /// \brief Matches extern "C" function declarations. /// /// Given: +/// \code /// extern "C" void f() {} /// extern "C" { void g() {} } /// void h() {} -/// function(isExternC()) +/// \endcode +/// functionDecl(isExternC()) /// matches the declaration of f and g, but not the declaration h AST_MATCHER(FunctionDecl, isExternC) { return Node.isExternC(); @@ -1537,7 +2005,9 @@ AST_MATCHER(FunctionDecl, isExternC) { /// or conditional operator. /// /// Example matches true (matcher = hasCondition(boolLiteral(equals(true)))) +/// \code /// if (true) {} +/// \endcode AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher<Expr>, InnerMatcher) { TOOLING_COMPILE_ASSERT( @@ -1555,7 +2025,9 @@ AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher<Expr>, /// \brief Matches the condition variable statement in an if statement. /// /// Given +/// \code /// if (A* a = GetAPointer()) {} +/// \endcode /// hasConditionVariableStatment(...) /// matches 'A* a = GetAPointer()'. AST_MATCHER_P(IfStmt, hasConditionVariableStatement, @@ -1569,29 +2041,33 @@ AST_MATCHER_P(IfStmt, hasConditionVariableStatement, /// \brief Matches the index expression of an array subscript expression. /// /// Given +/// \code /// int i[5]; /// void f() { i[1] = 42; } +/// \endcode /// arraySubscriptExpression(hasIndex(integerLiteral())) /// matches \c i[1] with the \c integerLiteral() matching \c 1 AST_MATCHER_P(ArraySubscriptExpr, hasIndex, - internal::Matcher<Expr>, matcher) { + internal::Matcher<Expr>, InnerMatcher) { if (const Expr* Expression = Node.getIdx()) - return matcher.matches(*Expression, Finder, Builder); + return InnerMatcher.matches(*Expression, Finder, Builder); return false; } /// \brief Matches the base expression of an array subscript expression. /// /// Given +/// \code /// int i[5]; /// void f() { i[1] = 42; } -/// arraySubscriptExpression(hasBase(implicitCast( -/// hasSourceExpression(declarationReference())))) -/// matches \c i[1] with the \c declarationReference() matching \c i +/// \endcode +/// arraySubscriptExpression(hasBase(implicitCastExpr( +/// hasSourceExpression(declRefExpr())))) +/// matches \c i[1] with the \c declRefExpr() matching \c i AST_MATCHER_P(ArraySubscriptExpr, hasBase, - internal::Matcher<Expr>, matcher) { + internal::Matcher<Expr>, InnerMatcher) { if (const Expr* Expression = Node.getBase()) - return matcher.matches(*Expression, Finder, Builder); + return InnerMatcher.matches(*Expression, Finder, Builder); return false; } @@ -1599,10 +2075,12 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, /// a given body. /// /// Given +/// \code /// for (;;) {} -/// hasBody(compoundStatement()) +/// \endcode +/// hasBody(compoundStmt()) /// matches 'for (;;) {}' -/// with compoundStatement() +/// with compoundStmt() /// matching '{}' AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher<Stmt>, InnerMatcher) { @@ -1620,10 +2098,12 @@ AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher<Stmt>, /// a given matcher. /// /// Given +/// \code /// { {}; 1+2; } -/// hasAnySubstatement(compoundStatement()) +/// \endcode +/// hasAnySubstatement(compoundStmt()) /// matches '{ {}; 1+2; }' -/// with compoundStatement() +/// with compoundStmt() /// matching '{}' AST_MATCHER_P(CompoundStmt, hasAnySubstatement, internal::Matcher<Stmt>, InnerMatcher) { @@ -1639,8 +2119,10 @@ AST_MATCHER_P(CompoundStmt, hasAnySubstatement, /// child statements. /// /// Example: Given +/// \code /// { for (;;) {} } -/// compoundStatement(statementCountIs(0))) +/// \endcode +/// compoundStmt(statementCountIs(0))) /// matches '{}' /// but does not match the outer compound statement. AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) { @@ -1650,7 +2132,9 @@ AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) { /// \brief Matches literals that are equal to the given value. /// /// Example matches true (matcher = boolLiteral(equals(true))) +/// \code /// true +/// \endcode /// /// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>, /// Matcher<FloatingLiteral>, Matcher<IntegerLiteral> @@ -1666,7 +2150,9 @@ equals(const ValueT &Value) { /// unary). /// /// Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) +/// \code /// !(a || b) +/// \endcode AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) { TOOLING_COMPILE_ASSERT( (llvm::is_base_of<BinaryOperator, NodeType>::value) || @@ -1678,7 +2164,9 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) { /// \brief Matches the left hand side of binary operator expressions. /// /// Example matches a (matcher = binaryOperator(hasLHS())) +/// \code /// a || b +/// \endcode AST_MATCHER_P(BinaryOperator, hasLHS, internal::Matcher<Expr>, InnerMatcher) { Expr *LeftHandSide = Node.getLHS(); @@ -1689,7 +2177,9 @@ AST_MATCHER_P(BinaryOperator, hasLHS, /// \brief Matches the right hand side of binary operator expressions. /// /// Example matches b (matcher = binaryOperator(hasRHS())) +/// \code /// a || b +/// \endcode AST_MATCHER_P(BinaryOperator, hasRHS, internal::Matcher<Expr>, InnerMatcher) { Expr *RightHandSide = Node.getRHS(); @@ -1706,8 +2196,10 @@ inline internal::Matcher<BinaryOperator> hasEitherOperand( /// \brief Matches if the operand of a unary operator matches. /// -/// Example matches true (matcher = hasOperand(boolLiteral(equals(true)))) +/// Example matches true (matcher = hasUnaryOperand(boolLiteral(equals(true)))) +/// \code /// !true +/// \endcode AST_MATCHER_P(UnaryOperator, hasUnaryOperand, internal::Matcher<Expr>, InnerMatcher) { const Expr * const Operand = Node.getSubExpr(); @@ -1718,8 +2210,8 @@ AST_MATCHER_P(UnaryOperator, hasUnaryOperand, /// \brief Matches if the cast's source expression matches the given matcher. /// /// Example: matches "a string" (matcher = -/// hasSourceExpression(constructorCall())) -/// +/// hasSourceExpression(constructExpr())) +/// \code /// class URL { URL(string); }; /// URL url = "a string"; AST_MATCHER_P(CastExpr, hasSourceExpression, @@ -1751,7 +2243,9 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType, /// \brief Matches the true branch expression of a conditional operator. /// /// Example matches a +/// \code /// condition ? a : b +/// \endcode AST_MATCHER_P(ConditionalOperator, hasTrueExpression, internal::Matcher<Expr>, InnerMatcher) { Expr *Expression = Node.getTrueExpr(); @@ -1762,7 +2256,9 @@ AST_MATCHER_P(ConditionalOperator, hasTrueExpression, /// \brief Matches the false branch expression of a conditional operator. /// /// Example matches b +/// \code /// condition ? a : b +/// \endcode AST_MATCHER_P(ConditionalOperator, hasFalseExpression, internal::Matcher<Expr>, InnerMatcher) { Expr *Expression = Node.getFalseExpr(); @@ -1773,12 +2269,14 @@ AST_MATCHER_P(ConditionalOperator, hasFalseExpression, /// \brief Matches if a declaration has a body attached. /// /// Example matches A, va, fa +/// \code /// class A {}; /// class B; // Doesn't match, as it has no body. /// int va; /// extern int vb; // Doesn't match, as it doesn't define the variable. /// void fa() {} /// void fb(); // Doesn't match, as it has no body. +/// \endcode /// /// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl> inline internal::PolymorphicMatcherWithParam0<internal::IsDefinitionMatcher> @@ -1795,13 +2293,15 @@ isDefinition() { /// this to? /// /// Example matches A() in the last line -/// (matcher = constructorCall(hasDeclaration(method( +/// (matcher = constructExpr(hasDeclaration(methodDecl( /// ofClass(hasName("A")))))) +/// \code /// class A { /// public: /// A(); /// }; /// A a = A(); +/// \endcode AST_MATCHER_P(CXXMethodDecl, ofClass, internal::Matcher<CXXRecordDecl>, InnerMatcher) { const CXXRecordDecl *Parent = Node.getParent(); @@ -1815,12 +2315,14 @@ AST_MATCHER_P(CXXMethodDecl, ofClass, /// Member calls on the implicit this pointer match as called with '->'. /// /// Given +/// \code /// class Y { /// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; } /// int a; /// static int b; /// }; -/// memberExpression(isArrow()) +/// \endcode +/// memberExpr(isArrow()) /// matches this->x, x, y.x, a, this->b inline internal::Matcher<MemberExpr> isArrow() { return makeMatcher(new internal::IsArrowMatcher()); @@ -1829,10 +2331,12 @@ inline internal::Matcher<MemberExpr> isArrow() { /// \brief Matches QualType nodes that are of integer type. /// /// Given +/// \code /// void a(int); /// void b(long); /// void c(double); -/// function(hasAnyParameter(hasType(isInteger()))) +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isInteger()))) /// matches "a(int)", "b(long)", but not "c(double)". AST_MATCHER(QualType, isInteger) { return Node->isIntegerType(); @@ -1842,12 +2346,14 @@ AST_MATCHER(QualType, isInteger) { /// include "top-level" const. /// /// Given +/// \code /// void a(int); /// void b(int const); /// void c(const int); /// void d(const int*); /// void e(int const) {}; -/// function(hasAnyParameter(hasType(isConstQualified()))) +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isConstQualified()))) /// matches "void b(int const)", "void c(const int)" and /// "void e(int const) {}". It does not match d as there /// is no top-level const on the parameter type "const int *". @@ -1859,10 +2365,12 @@ inline internal::Matcher<QualType> isConstQualified() { /// given matcher. /// /// Given +/// \code /// struct { int first, second; } first, second; /// int i(second.first); /// int j(first.second); -/// memberExpression(member(hasName("first"))) +/// \endcode +/// memberExpr(member(hasName("first"))) /// matches second.first /// but not first.second (because the member name there is "second"). AST_MATCHER_P(MemberExpr, member, @@ -1874,9 +2382,11 @@ AST_MATCHER_P(MemberExpr, member, /// matched by a given matcher. /// /// Given +/// \code /// struct X { int m; }; /// void f(X x) { x.m; m; } -/// memberExpression(hasObjectExpression(hasType(record(hasName("X"))))))) +/// \endcode +/// memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))) /// matches "x.m" and "m" /// with hasObjectExpression(...) /// matching "x" and the implicit object expression of "m" which has type X*. @@ -1888,15 +2398,17 @@ AST_MATCHER_P(MemberExpr, hasObjectExpression, /// \brief Matches any using shadow declaration. /// /// Given +/// \code /// namespace X { void b(); } /// using X::b; +/// \endcode /// usingDecl(hasAnyUsingShadowDecl(hasName("b")))) /// matches \code using X::b \endcode AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl, - internal::Matcher<UsingShadowDecl>, Matcher) { + internal::Matcher<UsingShadowDecl>, InnerMatcher) { for (UsingDecl::shadow_iterator II = Node.shadow_begin(); II != Node.shadow_end(); ++II) { - if (Matcher.matches(**II, Finder, Builder)) + if (InnerMatcher.matches(**II, Finder, Builder)) return true; } return false; @@ -1906,31 +2418,39 @@ AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl, /// matched by the given matcher. /// /// Given +/// \code /// namespace X { int a; void b(); } /// using X::a; /// using X::b; -/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(function()))) +/// \endcode +/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))) /// matches \code using X::b \endcode /// but not \code using X::a \endcode AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, - internal::Matcher<NamedDecl>, Matcher) { - return Matcher.matches(*Node.getTargetDecl(), Finder, Builder); + internal::Matcher<NamedDecl>, InnerMatcher) { + return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder); } /// \brief Matches template instantiations of function, class, or static /// member variable template instantiations. /// /// Given +/// \code /// template <typename T> class X {}; class A {}; X<A> x; +/// \endcode /// or +/// \code /// template <typename T> class X {}; class A {}; template class X<A>; -/// record(hasName("::X"), isTemplateInstantiation()) +/// \endcode +/// recordDecl(hasName("::X"), isTemplateInstantiation()) /// matches the template instantiation of X<A>. /// /// But given -/// template <typename T> class X {}; class A {}; +/// \code +/// template <typename T> class X {}; class A {}; /// template <> class X<A> {}; X<A> x; -/// record(hasName("::X"), isTemplateInstantiation()) +/// \endcode +/// recordDecl(hasName("::X"), isTemplateInstantiation()) /// does not match, as X<A> is an explicit template specialization. /// /// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> @@ -1941,6 +2461,411 @@ isTemplateInstantiation() { internal::IsTemplateInstantiationMatcher>(); } +/// \brief Matches explicit template specializations of function, class, or +/// static member variable template instantiations. +/// +/// Given +/// \code +/// template<typename T> void A(T t) { } +/// template<> void A(int N) { } +/// \endcode +/// functionDecl(isExplicitTemplateSpecialization()) +/// matches the specialization A<int>(). +/// +/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> +inline internal::PolymorphicMatcherWithParam0< + internal::IsExplicitTemplateSpecializationMatcher> +isExplicitTemplateSpecialization() { + return internal::PolymorphicMatcherWithParam0< + internal::IsExplicitTemplateSpecializationMatcher>(); +} + +/// \brief Matches \c TypeLocs for which the given inner +/// QualType-matcher matches. +inline internal::BindableMatcher<TypeLoc> loc( + const internal::Matcher<QualType> &InnerMatcher) { + return internal::BindableMatcher<TypeLoc>( + new internal::TypeLocTypeMatcher(InnerMatcher)); +} + +/// \brief Matches builtin Types. +/// +/// Given +/// \code +/// struct A {}; +/// A a; +/// int b; +/// float c; +/// bool d; +/// \endcode +/// builtinType() +/// matches "int b", "float c" and "bool d" +AST_TYPE_MATCHER(BuiltinType, builtinType); + +/// \brief Matches all kinds of arrays. +/// +/// Given +/// \code +/// int a[] = { 2, 3 }; +/// int b[4]; +/// void f() { int c[a[0]]; } +/// \endcode +/// arrayType() +/// matches "int a[]", "int b[4]" and "int c[a[0]]"; +AST_TYPE_MATCHER(ArrayType, arrayType); + +/// \brief Matches C99 complex types. +/// +/// Given +/// \code +/// _Complex float f; +/// \endcode +/// complexType() +/// matches "_Complex float f" +AST_TYPE_MATCHER(ComplexType, complexType); + +/// \brief Matches arrays and C99 complex types that have a specific element +/// type. +/// +/// Given +/// \code +/// struct A {}; +/// A a[7]; +/// int b[7]; +/// \endcode +/// arrayType(hasElementType(builtinType())) +/// matches "int b[7]" +/// +/// Usable as: Matcher<ArrayType>, Matcher<ComplexType> +AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement); + +/// \brief Matches C arrays with a specified constant size. +/// +/// Given +/// \code +/// void() { +/// int a[2]; +/// int b[] = { 2, 3 }; +/// int c[b[0]]; +/// } +/// \endcode +/// constantArrayType() +/// matches "int a[2]" +AST_TYPE_MATCHER(ConstantArrayType, constantArrayType); + +/// \brief Matches \c ConstantArrayType nodes that have the specified size. +/// +/// Given +/// \code +/// int a[42]; +/// int b[2 * 21]; +/// int c[41], d[43]; +/// \endcode +/// constantArrayType(hasSize(42)) +/// matches "int a[42]" and "int b[2 * 21]" +AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) { + return Node.getSize() == N; +} + +/// \brief Matches C++ arrays whose size is a value-dependent expression. +/// +/// Given +/// \code +/// template<typename T, int Size> +/// class array { +/// T data[Size]; +/// }; +/// \endcode +/// dependentSizedArrayType +/// matches "T data[Size]" +AST_TYPE_MATCHER(DependentSizedArrayType, dependentSizedArrayType); + +/// \brief Matches C arrays with unspecified size. +/// +/// Given +/// \code +/// int a[] = { 2, 3 }; +/// int b[42]; +/// void f(int c[]) { int d[a[0]]; }; +/// \endcode +/// incompleteArrayType() +/// matches "int a[]" and "int c[]" +AST_TYPE_MATCHER(IncompleteArrayType, incompleteArrayType); + +/// \brief Matches C arrays with a specified size that is not an +/// integer-constant-expression. +/// +/// Given +/// \code +/// void f() { +/// int a[] = { 2, 3 } +/// int b[42]; +/// int c[a[0]]; +/// \endcode +/// variableArrayType() +/// matches "int c[a[0]]" +AST_TYPE_MATCHER(VariableArrayType, variableArrayType); + +/// \brief Matches \c VariableArrayType nodes that have a specific size +/// expression. +/// +/// Given +/// \code +/// void f(int b) { +/// int a[b]; +/// } +/// \endcode +/// variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to( +/// varDecl(hasName("b"))))))) +/// matches "int a[b]" +AST_MATCHER_P(VariableArrayType, hasSizeExpr, + internal::Matcher<Expr>, InnerMatcher) { + return InnerMatcher.matches(*Node.getSizeExpr(), Finder, Builder); +} + +/// \brief Matches atomic types. +/// +/// Given +/// \code +/// _Atomic(int) i; +/// \endcode +/// atomicType() +/// matches "_Atomic(int) i" +AST_TYPE_MATCHER(AtomicType, atomicType); + +/// \brief Matches atomic types with a specific value type. +/// +/// Given +/// \code +/// _Atomic(int) i; +/// _Atomic(float) f; +/// \endcode +/// atomicType(hasValueType(isInteger())) +/// matches "_Atomic(int) i" +/// +/// Usable as: Matcher<AtomicType> +AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue); + +/// \brief Matches types nodes representing C++11 auto types. +/// +/// Given: +/// \code +/// auto n = 4; +/// int v[] = { 2, 3 } +/// for (auto i : v) { } +/// \endcode +/// autoType() +/// matches "auto n" and "auto i" +AST_TYPE_MATCHER(AutoType, autoType); + +/// \brief Matches \c AutoType nodes where the deduced type is a specific type. +/// +/// Note: There is no \c TypeLoc for the deduced type and thus no +/// \c getDeducedLoc() matcher. +/// +/// Given +/// \code +/// auto a = 1; +/// auto b = 2.0; +/// \endcode +/// autoType(hasDeducedType(isInteger())) +/// matches "auto a" +/// +/// Usable as: Matcher<AutoType> +AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType); + +/// \brief Matches \c FunctionType nodes. +/// +/// Given +/// \code +/// int (*f)(int); +/// void g(); +/// \endcode +/// functionType() +/// matches "int (*f)(int)" and the type of "g". +AST_TYPE_MATCHER(FunctionType, functionType); + +/// \brief Matches block pointer types, i.e. types syntactically represented as +/// "void (^)(int)". +/// +/// The \c pointee is always required to be a \c FunctionType. +AST_TYPE_MATCHER(BlockPointerType, blockPointerType); + +/// \brief Matches member pointer types. +/// Given +/// \code +/// struct A { int i; } +/// A::* ptr = A::i; +/// \endcode +/// memberPointerType() +/// matches "A::* ptr" +AST_TYPE_MATCHER(MemberPointerType, memberPointerType); + +/// \brief Matches pointer types. +/// +/// Given +/// \code +/// int *a; +/// int &b = *a; +/// int c = 5; +/// \endcode +/// pointerType() +/// matches "int *a" +AST_TYPE_MATCHER(PointerType, pointerType); + +/// \brief Matches reference types. +/// +/// Given +/// \code +/// int *a; +/// int &b = *a; +/// int c = 5; +/// \endcode +/// pointerType() +/// matches "int &b" +AST_TYPE_MATCHER(ReferenceType, referenceType); + +/// \brief Narrows PointerType (and similar) matchers to those where the +/// \c pointee matches a given matcher. +/// +/// Given +/// \code +/// int *a; +/// int const *b; +/// float const *f; +/// \endcode +/// pointerType(pointee(isConstQualified(), isInteger())) +/// matches "int const *b" +/// +/// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, +/// Matcher<PointerType>, Matcher<ReferenceType> +AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee); + +/// \brief Matches typedef types. +/// +/// Given +/// \code +/// typedef int X; +/// \endcode +/// typedefType() +/// matches "typedef int X" +AST_TYPE_MATCHER(TypedefType, typedefType); + +/// \brief Matches \c TypedefTypes referring to a specific +/// \c TypedefNameDecl. +AST_MATCHER_P(TypedefType, hasDecl, + internal::Matcher<TypedefNameDecl>, InnerMatcher) { + return InnerMatcher.matches(*Node.getDecl(), Finder, Builder); +} + +/// \brief Matches nested name specifiers. +/// +/// Given +/// \code +/// namespace ns { +/// struct A { static void f(); }; +/// void A::f() {} +/// void g() { A::f(); } +/// } +/// ns::A a; +/// \endcode +/// nestedNameSpecifier() +/// matches "ns::" and both "A::" +const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier; + +/// \brief Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc. +const internal::VariadicAllOfMatcher< + NestedNameSpecifierLoc> nestedNameSpecifierLoc; + +/// \brief Matches \c NestedNameSpecifierLocs for which the given inner +/// NestedNameSpecifier-matcher matches. +inline internal::BindableMatcher<NestedNameSpecifierLoc> loc( + const internal::Matcher<NestedNameSpecifier> &InnerMatcher) { + return internal::BindableMatcher<NestedNameSpecifierLoc>( + new internal::LocMatcher<NestedNameSpecifierLoc, NestedNameSpecifier>( + InnerMatcher)); +} + +/// \brief Matches nested name specifiers that specify a type matching the +/// given \c QualType matcher without qualifiers. +/// +/// Given +/// \code +/// struct A { struct B { struct C {}; }; }; +/// A::B::C c; +/// \endcode +/// nestedNameSpecifier(specifiesType(hasDeclaration(recordDecl(hasName("A"))))) +/// matches "A::" +AST_MATCHER_P(NestedNameSpecifier, specifiesType, + internal::Matcher<QualType>, InnerMatcher) { + if (Node.getAsType() == NULL) + return false; + return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder); +} + +/// \brief Matches nested name specifier locs that specify a type matching the +/// given \c TypeLoc. +/// +/// Given +/// \code +/// struct A { struct B { struct C {}; }; }; +/// A::B::C c; +/// \endcode +/// nestedNameSpecifierLoc(specifiesTypeLoc(loc(type( +/// hasDeclaration(recordDecl(hasName("A"))))))) +/// matches "A::" +AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc, + internal::Matcher<TypeLoc>, InnerMatcher) { + return InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder); +} + +/// \brief Matches on the prefix of a \c NestedNameSpecifier. +/// +/// Given +/// \code +/// struct A { struct B { struct C {}; }; }; +/// A::B::C c; +/// \endcode +/// nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A")))) and +/// matches "A::" +inline internal::Matcher<NestedNameSpecifier> hasPrefix( + const internal::Matcher<NestedNameSpecifier> &InnerMatcher) { + return internal::makeMatcher( + new internal::NestedNameSpecifierPrefixMatcher(InnerMatcher)); +} + +/// \brief Matches on the prefix of a \c NestedNameSpecifierLoc. +/// +/// Given +/// \code +/// struct A { struct B { struct C {}; }; }; +/// A::B::C c; +/// \endcode +/// nestedNameSpecifierLoc(hasPrefix(loc(specifiesType(asString("struct A"))))) +/// matches "A::" +inline internal::Matcher<NestedNameSpecifierLoc> hasPrefix( + const internal::Matcher<NestedNameSpecifierLoc> &InnerMatcher) { + return internal::makeMatcher( + new internal::NestedNameSpecifierLocPrefixMatcher(InnerMatcher)); +} + +/// \brief Matches nested name specifiers that specify a namespace matching the +/// given namespace matcher. +/// +/// Given +/// \code +/// namespace ns { struct A {}; } +/// ns::A a; +/// \endcode +/// nestedNameSpecifier(specifiesNamespace(hasName("ns"))) +/// matches "ns::" +AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace, + internal::Matcher<NamespaceDecl>, InnerMatcher) { + if (Node.getAsNamespace() == NULL) + return false; + return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder); +} + } // end namespace ast_matchers } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index 3f55685..e5365ff 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -39,7 +39,11 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/Stmt.h" +#include "clang/AST/StmtCXX.h" +#include "clang/AST/Type.h" +#include "clang/ASTMatchers/ASTTypeTraits.h" #include "llvm/ADT/VariadicFunction.h" +#include "llvm/Support/type_traits.h" #include <map> #include <string> #include <vector> @@ -57,6 +61,45 @@ class BoundNodes; namespace internal { class BoundNodesTreeBuilder; +/// \brief Internal version of BoundNodes. Holds all the bound nodes. +class BoundNodesMap { +public: + /// \brief Adds \c Node to the map with key \c ID. + /// + /// The node's base type should be in NodeBaseType or it will be unaccessible. + template <typename T> + void addNode(StringRef ID, const T* Node) { + NodeMap[ID] = ast_type_traits::DynTypedNode::create(*Node); + } + void addNode(StringRef ID, ast_type_traits::DynTypedNode Node) { + NodeMap[ID] = Node; + } + + /// \brief Returns the AST node bound to \c ID. + /// + /// Returns NULL if there was no node bound to \c ID or if there is a node but + /// it cannot be converted to the specified type. + template <typename T> + const T *getNodeAs(StringRef ID) const { + IDToNodeMap::const_iterator It = NodeMap.find(ID); + if (It == NodeMap.end()) { + return NULL; + } + return It->second.get<T>(); + } + + /// \brief Copies all ID/Node pairs to BoundNodesTreeBuilder \c Builder. + void copyTo(BoundNodesTreeBuilder *Builder) const; + + /// \brief Copies all ID/Node pairs to BoundNodesMap \c Other. + void copyTo(BoundNodesMap *Other) const; + +private: + /// \brief A map from IDs to the bound nodes. + typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap; + + IDToNodeMap NodeMap; +}; /// \brief A tree of bound nodes in match results. /// @@ -84,11 +127,10 @@ public: BoundNodesTree(); /// \brief Create a BoundNodesTree from pre-filled maps of bindings. - BoundNodesTree(const std::map<std::string, const Decl*>& DeclBindings, - const std::map<std::string, const Stmt*>& StmtBindings, + BoundNodesTree(const BoundNodesMap& Bindings, const std::vector<BoundNodesTree> RecursiveBindings); - /// \brief Adds all bound nodes to bound_nodes_builder. + /// \brief Adds all bound nodes to \c Builder. void copyTo(BoundNodesTreeBuilder* Builder) const; /// \brief Visits all matches that this BoundNodesTree represents. @@ -99,17 +141,12 @@ public: private: void visitMatchesRecursively( Visitor* ResultVistior, - std::map<std::string, const Decl*> DeclBindings, - std::map<std::string, const Stmt*> StmtBindings); - - template <typename T> - void copyBindingsTo(const T& bindings, BoundNodesTreeBuilder* Builder) const; + const BoundNodesMap& AggregatedBindings); // FIXME: Find out whether we want to use different data structures here - // first benchmarks indicate that it doesn't matter though. - std::map<std::string, const Decl*> DeclBindings; - std::map<std::string, const Stmt*> StmtBindings; + BoundNodesMap Bindings; std::vector<BoundNodesTree> RecursiveBindings; }; @@ -123,12 +160,13 @@ public: BoundNodesTreeBuilder(); /// \brief Add a binding from an id to a node. - /// - /// FIXME: Add overloads for all AST base types. - /// @{ - void setBinding(const std::string &Id, const Decl *Node); - void setBinding(const std::string &Id, const Stmt *Node); - /// @} + template <typename T> + void setBinding(const std::string &Id, const T *Node) { + Bindings.addNode(Id, Node); + } + void setBinding(const std::string &Id, ast_type_traits::DynTypedNode Node) { + Bindings.addNode(Id, Node); + } /// \brief Adds a branch in the tree. void addMatch(const BoundNodesTree& Bindings); @@ -137,11 +175,10 @@ public: BoundNodesTree build() const; private: - BoundNodesTreeBuilder(const BoundNodesTreeBuilder&); // DO NOT IMPLEMENT - void operator=(const BoundNodesTreeBuilder&); // DO NOT IMPLEMENT + BoundNodesTreeBuilder(const BoundNodesTreeBuilder &) LLVM_DELETED_FUNCTION; + void operator=(const BoundNodesTreeBuilder &) LLVM_DELETED_FUNCTION; - std::map<std::string, const Decl*> DeclBindings; - std::map<std::string, const Stmt*> StmtBindings; + BoundNodesMap Bindings; std::vector<BoundNodesTree> RecursiveBindings; }; @@ -169,7 +206,8 @@ public: BoundNodesTreeBuilder *Builder) const = 0; }; -/// \brief Interface for matchers that only evaluate properties on a single node. +/// \brief Interface for matchers that only evaluate properties on a single +/// node. template <typename T> class SingleNodeMatcherInterface : public MatcherInterface<T> { public: @@ -187,6 +225,24 @@ private: } }; +/// \brief Base class for all matchers that works on a \c DynTypedNode. +/// +/// Matcher implementations will check whether the \c DynTypedNode is +/// convertible into the respecitve types and then do the actual match +/// on the actual node, or return false if it is not convertible. +class DynTypedMatcher { +public: + virtual ~DynTypedMatcher() {} + + /// \brief Returns true if the matcher matches the given \c DynNode. + virtual bool matches(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const = 0; + + /// \brief Returns a unique ID for the matcher. + virtual uint64_t getID() const = 0; +}; + /// \brief Wrapper of a MatcherInterface<T> *that allows copying. /// /// A Matcher<Base> can be used anywhere a Matcher<Derived> is @@ -196,12 +252,32 @@ private: /// operator rather than a type hierarchy to be able to templatize the /// type hierarchy instead of spelling it out. template <typename T> -class Matcher { +class Matcher : public DynTypedMatcher { public: /// \brief Takes ownership of the provided implementation pointer. explicit Matcher(MatcherInterface<T> *Implementation) : Implementation(Implementation) {} + /// \brief Implicitly converts \c Other to a Matcher<T>. + /// + /// Requires \c T to be derived from \c From. + template <typename From> + Matcher(const Matcher<From> &Other, + typename llvm::enable_if_c< + llvm::is_base_of<From, T>::value && + !llvm::is_same<From, T>::value >::type* = 0) + : Implementation(new ImplicitCastMatcher<From>(Other)) {} + + /// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>. + /// + /// The resulting matcher is not strict, i.e. ignores qualifiers. + template <typename TypeT> + Matcher(const Matcher<TypeT> &Other, + typename llvm::enable_if_c< + llvm::is_same<T, QualType>::value && + llvm::is_same<TypeT, Type>::value >::type* = 0) + : Implementation(new TypeToQualType<TypeT>(Other)) {} + /// \brief Forwards the call to the underlying MatcherInterface<T> pointer. bool matches(const T &Node, ASTMatchFinder *Finder, @@ -209,14 +285,6 @@ public: return Implementation->matches(Node, Finder, Builder); } - /// \brief Implicitly converts this object to a Matcher<Derived>. - /// - /// Requires Derived to be derived from T. - template <typename Derived> - operator Matcher<Derived>() const { - return Matcher<Derived>(new ImplicitCastMatcher<Derived>(*this)); - } - /// \brief Returns an ID that uniquely identifies the matcher. uint64_t getID() const { /// FIXME: Document the requirements this imposes on matcher @@ -224,23 +292,55 @@ public: return reinterpret_cast<uint64_t>(Implementation.getPtr()); } + /// \brief Returns whether the matcher matches on the given \c DynNode. + virtual bool matches(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + const T *Node = DynNode.get<T>(); + if (!Node) return false; + return matches(*Node, Finder, Builder); + } + + /// \brief Allows the conversion of a \c Matcher<Type> to a \c + /// Matcher<QualType>. + /// + /// Depending on the constructor argument, the matcher is either strict, i.e. + /// does only matches in the absence of qualifiers, or not, i.e. simply + /// ignores any qualifiers. + template <typename TypeT> + class TypeToQualType : public MatcherInterface<QualType> { + public: + TypeToQualType(const Matcher<TypeT> &InnerMatcher) + : InnerMatcher(InnerMatcher) {} + + virtual bool matches(const QualType &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + if (Node.isNull()) + return false; + return InnerMatcher.matches(*Node, Finder, Builder); + } + private: + const Matcher<TypeT> InnerMatcher; + }; + private: - /// \brief Allows conversion from Matcher<T> to Matcher<Derived> if Derived - /// is derived from T. - template <typename Derived> - class ImplicitCastMatcher : public MatcherInterface<Derived> { + /// \brief Allows conversion from Matcher<Base> to Matcher<T> if T + /// is derived from Base. + template <typename Base> + class ImplicitCastMatcher : public MatcherInterface<T> { public: - explicit ImplicitCastMatcher(const Matcher<T> &From) + explicit ImplicitCastMatcher(const Matcher<Base> &From) : From(From) {} - virtual bool matches(const Derived &Node, + virtual bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { return From.matches(Node, Finder, Builder); } private: - const Matcher<T> From; + const Matcher<Base> From; }; llvm::IntrusiveRefCntPtr< MatcherInterface<T> > Implementation; @@ -280,18 +380,14 @@ private: /// FIXME: Add other ways to convert... if (Node.isNull()) return false; - CXXRecordDecl *NodeAsRecordDecl = Node->getAsCXXRecordDecl(); - return NodeAsRecordDecl != NULL && - InnerMatcher.matches(*NodeAsRecordDecl, Finder, Builder); + return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder); } /// \brief Extracts the Decl of the callee of a CallExpr and returns whether /// the inner matcher matches on it. bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - const Decl *NodeAsDecl = Node.getCalleeDecl(); - return NodeAsDecl != NULL && - InnerMatcher.matches(*NodeAsDecl, Finder, Builder); + return matchesDecl(Node.getCalleeDecl(), Finder, Builder); } /// \brief Extracts the Decl of the constructor call and returns whether the @@ -299,96 +395,63 @@ private: bool matchesSpecialized(const CXXConstructExpr &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - const Decl *NodeAsDecl = Node.getConstructor(); - return NodeAsDecl != NULL && - InnerMatcher.matches(*NodeAsDecl, Finder, Builder); + return matchesDecl(Node.getConstructor(), Finder, Builder); + } + + /// \brief Extracts the \c ValueDecl a \c MemberExpr refers to and returns + /// whether the inner matcher matches on it. + bool matchesSpecialized(const MemberExpr &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return matchesDecl(Node.getMemberDecl(), Finder, Builder); + } + + /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node + /// is \c NULL. + bool matchesDecl(const Decl *Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return Node != NULL && InnerMatcher.matches(*Node, Finder, Builder); } const Matcher<Decl> InnerMatcher; }; /// \brief IsBaseType<T>::value is true if T is a "base" type in the AST -/// node class hierarchies (i.e. if T is Decl, Stmt, or QualType). +/// node class hierarchies. template <typename T> struct IsBaseType { static const bool value = (llvm::is_same<T, Decl>::value || llvm::is_same<T, Stmt>::value || llvm::is_same<T, QualType>::value || + llvm::is_same<T, Type>::value || + llvm::is_same<T, TypeLoc>::value || + llvm::is_same<T, NestedNameSpecifier>::value || + llvm::is_same<T, NestedNameSpecifierLoc>::value || llvm::is_same<T, CXXCtorInitializer>::value); }; template <typename T> const bool IsBaseType<T>::value; -/// \brief Interface that can match any AST base node type and contains default -/// implementations returning false. -class UntypedBaseMatcher : public llvm::RefCountedBaseVPTR { -public: - virtual ~UntypedBaseMatcher() {} - - virtual bool matches(const Decl &DeclNode, ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { - return false; - } - virtual bool matches(const QualType &TypeNode, ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { - return false; - } - virtual bool matches(const Stmt &StmtNode, ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { - return false; - } - virtual bool matches(const CXXCtorInitializer &CtorInitNode, - ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { - return false; - } - - /// \brief Returns a unique ID for the matcher. - virtual uint64_t getID() const = 0; -}; - -/// \brief An UntypedBaseMatcher that overwrites the Matches(...) method for -/// node type T. T must be an AST base type. -template <typename T> -class TypedBaseMatcher : public UntypedBaseMatcher { - TOOLING_COMPILE_ASSERT(IsBaseType<T>::value, - typed_base_matcher_can_only_be_used_with_base_type); -public: - explicit TypedBaseMatcher(const Matcher<T> &InnerMatcher) - : InnerMatcher(InnerMatcher) {} - - using UntypedBaseMatcher::matches; - /// \brief Implements UntypedBaseMatcher::Matches. - /// - /// Since T is guaranteed to be a "base" AST node type, this method is - /// guaranteed to override one of the matches() methods from - /// UntypedBaseMatcher. - virtual bool matches(const T &Node, - ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { - return InnerMatcher.matches(Node, Finder, Builder); - } - - /// \brief Implements UntypedBaseMatcher::getID. - virtual uint64_t getID() const { - return InnerMatcher.getID(); - } - -private: - Matcher<T> InnerMatcher; -}; - /// \brief Interface that allows matchers to traverse the AST. /// FIXME: Find a better name. /// -/// This provides two entry methods for each base node type in the AST: -/// - matchesChildOf: +/// This provides three entry methods for each base node type in the AST: +/// - \c matchesChildOf: /// Matches a matcher on every child node of the given node. Returns true /// if at least one child node could be matched. -/// - matchesDescendantOf: +/// - \c matchesDescendantOf: /// Matches a matcher on all descendant nodes of the given node. Returns true /// if at least one descendant matched. +/// - \c matchesAncestorOf: +/// Matches a matcher on all ancestors of the given node. Returns true if +/// at least one ancestor matched. +/// +/// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal. +/// In the future, we wan to implement this for all nodes for which it makes +/// sense. In the case of matchesAncestorOf, we'll want to implement it for +/// all nodes, as all nodes have ancestors. class ASTMatchFinder { public: /// \brief Defines how we descend a level in the AST when we pass @@ -408,6 +471,14 @@ public: BK_All }; + /// \brief Defines which ancestors are considered for a match. + enum AncestorMatchMode { + /// All ancestors. + AMM_All, + /// Direct parent only. + AMM_ParentOnly + }; + virtual ~ASTMatchFinder() {} /// \brief Returns true if the given class is directly or indirectly derived @@ -418,26 +489,70 @@ public: const Matcher<NamedDecl> &Base, BoundNodesTreeBuilder *Builder) = 0; - // FIXME: Implement for other base nodes. - virtual bool matchesChildOf(const Decl &DeclNode, - const UntypedBaseMatcher &BaseMatcher, - BoundNodesTreeBuilder *Builder, - TraversalKind Traverse, - BindKind Bind) = 0; - virtual bool matchesChildOf(const Stmt &StmtNode, - const UntypedBaseMatcher &BaseMatcher, + template <typename T> + bool matchesChildOf(const T &Node, + const DynTypedMatcher &Matcher, + BoundNodesTreeBuilder *Builder, + TraversalKind Traverse, + BindKind Bind) { + TOOLING_COMPILE_ASSERT( + (llvm::is_base_of<Decl, T>::value || + llvm::is_base_of<Stmt, T>::value || + llvm::is_base_of<NestedNameSpecifier, T>::value || + llvm::is_base_of<NestedNameSpecifierLoc, T>::value || + llvm::is_base_of<TypeLoc, T>::value || + llvm::is_base_of<QualType, T>::value), + unsupported_type_for_recursive_matching); + return matchesChildOf(ast_type_traits::DynTypedNode::create(Node), + Matcher, Builder, Traverse, Bind); + } + + template <typename T> + bool matchesDescendantOf(const T &Node, + const DynTypedMatcher &Matcher, + BoundNodesTreeBuilder *Builder, + BindKind Bind) { + TOOLING_COMPILE_ASSERT( + (llvm::is_base_of<Decl, T>::value || + llvm::is_base_of<Stmt, T>::value || + llvm::is_base_of<NestedNameSpecifier, T>::value || + llvm::is_base_of<NestedNameSpecifierLoc, T>::value || + llvm::is_base_of<TypeLoc, T>::value || + llvm::is_base_of<QualType, T>::value), + unsupported_type_for_recursive_matching); + return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node), + Matcher, Builder, Bind); + } + + // FIXME: Implement support for BindKind. + template <typename T> + bool matchesAncestorOf(const T &Node, + const DynTypedMatcher &Matcher, + BoundNodesTreeBuilder *Builder, + AncestorMatchMode MatchMode) { + TOOLING_COMPILE_ASSERT((llvm::is_base_of<Decl, T>::value || + llvm::is_base_of<Stmt, T>::value), + only_Decl_or_Stmt_allowed_for_recursive_matching); + return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node), + Matcher, Builder, MatchMode); + } + +protected: + virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, + const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, TraversalKind Traverse, BindKind Bind) = 0; - virtual bool matchesDescendantOf(const Decl &DeclNode, - const UntypedBaseMatcher &BaseMatcher, - BoundNodesTreeBuilder *Builder, - BindKind Bind) = 0; - virtual bool matchesDescendantOf(const Stmt &StmtNode, - const UntypedBaseMatcher &BaseMatcher, + virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node, + const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, BindKind Bind) = 0; + + virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node, + const DynTypedMatcher &Matcher, + BoundNodesTreeBuilder *Builder, + AncestorMatchMode MatchMode) = 0; }; /// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by @@ -606,9 +721,6 @@ public: /// The returned matcher is equivalent to this matcher, but will /// bind the matched node on a match. Matcher<T> bind(StringRef ID) const { - TOOLING_COMPILE_ASSERT((llvm::is_base_of<Stmt, T>::value || - llvm::is_base_of<Decl, T>::value), - trying_to_bind_unsupported_node_type__only_decl_and_stmt_supported); return Matcher<T>(new IdMatcher<T>(ID, *this)); } }; @@ -635,7 +747,7 @@ public: } private: - const TypedBaseMatcher<ChildT> ChildMatcher; + const Matcher<ChildT> ChildMatcher; }; /// \brief Matches nodes of type T that have child nodes of type ChildT for @@ -661,7 +773,7 @@ class ForEachMatcher : public MatcherInterface<T> { } private: - const TypedBaseMatcher<ChildT> ChildMatcher; + const Matcher<ChildT> ChildMatcher; }; /// \brief Matches nodes of type T if the given Matcher<T> does not match. @@ -733,6 +845,20 @@ private: const Matcher<T> InnertMatcher2; }; +/// \brief Creates a Matcher<T> that matches if all inner matchers match. +template<typename T> +BindableMatcher<T> makeAllOfComposite( + ArrayRef<const Matcher<T> *> InnerMatchers) { + if (InnerMatchers.empty()) + return BindableMatcher<T>(new TrueMatcher<T>); + MatcherInterface<T> *InnerMatcher = new TrueMatcher<T>; + for (int i = InnerMatchers.size() - 1; i >= 0; --i) { + InnerMatcher = new AllOfMatcher<T, Matcher<T>, Matcher<T> >( + *InnerMatchers[i], makeMatcher(InnerMatcher)); + } + return BindableMatcher<T>(InnerMatcher); +} + /// \brief Creates a Matcher<T> that matches if /// T is dyn_cast'able into InnerT and all inner matchers match. /// @@ -742,17 +868,8 @@ private: template<typename T, typename InnerT> BindableMatcher<T> makeDynCastAllOfComposite( ArrayRef<const Matcher<InnerT> *> InnerMatchers) { - if (InnerMatchers.empty()) { - Matcher<InnerT> InnerMatcher = makeMatcher(new TrueMatcher<InnerT>); - return BindableMatcher<T>(new DynCastMatcher<T, InnerT>(InnerMatcher)); - } - Matcher<InnerT> InnerMatcher = *InnerMatchers.back(); - for (int i = InnerMatchers.size() - 2; i >= 0; --i) { - InnerMatcher = makeMatcher( - new AllOfMatcher<InnerT, Matcher<InnerT>, Matcher<InnerT> >( - *InnerMatchers[i], InnerMatcher)); - } - return BindableMatcher<T>(new DynCastMatcher<T, InnerT>(InnerMatcher)); + return BindableMatcher<T>(new DynCastMatcher<T, InnerT>( + makeAllOfComposite(InnerMatchers))); } /// \brief Matches nodes of type T that have at least one descendant node of @@ -775,7 +892,53 @@ public: } private: - const TypedBaseMatcher<DescendantT> DescendantMatcher; + const Matcher<DescendantT> DescendantMatcher; +}; + +/// \brief Matches nodes of type \c T that have a parent node of type \c ParentT +/// for which the given inner matcher matches. +/// +/// \c ParentT must be an AST base type. +template <typename T, typename ParentT> +class HasParentMatcher : public MatcherInterface<T> { + TOOLING_COMPILE_ASSERT(IsBaseType<ParentT>::value, + has_parent_only_accepts_base_type_matcher); +public: + explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher) + : ParentMatcher(ParentMatcher) {} + + virtual bool matches(const T &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return Finder->matchesAncestorOf( + Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly); + } + + private: + const Matcher<ParentT> ParentMatcher; +}; + +/// \brief Matches nodes of type \c T that have at least one ancestor node of +/// type \c AncestorT for which the given inner matcher matches. +/// +/// \c AncestorT must be an AST base type. +template <typename T, typename AncestorT> +class HasAncestorMatcher : public MatcherInterface<T> { + TOOLING_COMPILE_ASSERT(IsBaseType<AncestorT>::value, + has_ancestor_only_accepts_base_type_matcher); +public: + explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher) + : AncestorMatcher(AncestorMatcher) {} + + virtual bool matches(const T &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return Finder->matchesAncestorOf( + Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All); + } + + private: + const Matcher<AncestorT> AncestorMatcher; }; /// \brief Matches nodes of type T that have at least one descendant node of @@ -801,7 +964,7 @@ class ForEachDescendantMatcher : public MatcherInterface<T> { } private: - const TypedBaseMatcher<DescendantT> DescendantMatcher; + const Matcher<DescendantT> DescendantMatcher; }; /// \brief Matches on nodes that have a getValue() method if getValue() equals @@ -858,6 +1021,22 @@ class IsTemplateInstantiationMatcher : public MatcherInterface<T> { } }; +/// \brief Matches on explicit template specializations for FunctionDecl, +/// VarDecl or CXXRecordDecl nodes. +template <typename T> +class IsExplicitTemplateSpecializationMatcher : public MatcherInterface<T> { + TOOLING_COMPILE_ASSERT((llvm::is_base_of<FunctionDecl, T>::value) || + (llvm::is_base_of<VarDecl, T>::value) || + (llvm::is_base_of<CXXRecordDecl, T>::value), + requires_getTemplateSpecializationKind_method); + public: + virtual bool matches(const T& Node, + ASTMatchFinder* Finder, + BoundNodesTreeBuilder* Builder) const { + return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization); + } +}; + class IsArrowMatcher : public SingleNodeMatcherInterface<MemberExpr> { public: virtual bool matchesNode(const MemberExpr &Node) const { @@ -894,6 +1073,166 @@ public: VariadicDynCastAllOfMatcher() {} }; +/// \brief A \c VariadicAllOfMatcher<T> object is a variadic functor that takes +/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T +/// nodes that are matched by all of the given matchers. +/// +/// For example: +/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier; +/// Creates a functor nestedNameSpecifier(...) that creates a +/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type +/// \c Matcher<NestedNameSpecifier>. +/// The returned matcher matches if all given matchers match. +template <typename T> +class VariadicAllOfMatcher : public llvm::VariadicFunction< + BindableMatcher<T>, Matcher<T>, + makeAllOfComposite<T> > { +public: + VariadicAllOfMatcher() {} +}; + +/// \brief Matches nodes of type \c TLoc for which the inner +/// \c Matcher<T> matches. +template <typename TLoc, typename T> +class LocMatcher : public MatcherInterface<TLoc> { +public: + explicit LocMatcher(const Matcher<T> &InnerMatcher) + : InnerMatcher(InnerMatcher) {} + + virtual bool matches(const TLoc &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + if (!Node) + return false; + return InnerMatcher.matches(*extract(Node), Finder, Builder); + } + +private: + const NestedNameSpecifier *extract(const NestedNameSpecifierLoc &Loc) const { + return Loc.getNestedNameSpecifier(); + } + + const Matcher<T> InnerMatcher; +}; + +/// \brief Matches \c NestedNameSpecifiers with a prefix matching another +/// \c Matcher<NestedNameSpecifier>. +class NestedNameSpecifierPrefixMatcher + : public MatcherInterface<NestedNameSpecifier> { +public: + explicit NestedNameSpecifierPrefixMatcher( + const Matcher<NestedNameSpecifier> &InnerMatcher) + : InnerMatcher(InnerMatcher) {} + + virtual bool matches(const NestedNameSpecifier &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + NestedNameSpecifier *NextNode = Node.getPrefix(); + if (NextNode == NULL) + return false; + return InnerMatcher.matches(*NextNode, Finder, Builder); + } + +private: + const Matcher<NestedNameSpecifier> InnerMatcher; +}; + +/// \brief Matches \c NestedNameSpecifierLocs with a prefix matching another +/// \c Matcher<NestedNameSpecifierLoc>. +class NestedNameSpecifierLocPrefixMatcher + : public MatcherInterface<NestedNameSpecifierLoc> { +public: + explicit NestedNameSpecifierLocPrefixMatcher( + const Matcher<NestedNameSpecifierLoc> &InnerMatcher) + : InnerMatcher(InnerMatcher) {} + + virtual bool matches(const NestedNameSpecifierLoc &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + NestedNameSpecifierLoc NextNode = Node.getPrefix(); + if (!NextNode) + return false; + return InnerMatcher.matches(NextNode, Finder, Builder); + } + +private: + const Matcher<NestedNameSpecifierLoc> InnerMatcher; +}; + +/// \brief Matches \c TypeLocs based on an inner matcher matching a certain +/// \c QualType. +/// +/// Used to implement the \c loc() matcher. +class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> { +public: + explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher) + : InnerMatcher(InnerMatcher) {} + + virtual bool matches(const TypeLoc &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + if (!Node) + return false; + return InnerMatcher.matches(Node.getType(), Finder, Builder); + } + +private: + const Matcher<QualType> InnerMatcher; +}; + +/// \brief Matches nodes of type \c T for which the inner matcher matches on a +/// another node of type \c T that can be reached using a given traverse +/// function. +template <typename T> +class TypeTraverseMatcher : public MatcherInterface<T> { +public: + explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher, + QualType (T::*TraverseFunction)() const) + : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} + + virtual bool matches(const T &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + QualType NextNode = (Node.*TraverseFunction)(); + if (NextNode.isNull()) + return false; + return InnerMatcher.matches(NextNode, Finder, Builder); + } + +private: + const Matcher<QualType> InnerMatcher; + QualType (T::*TraverseFunction)() const; +}; + +/// \brief Matches nodes of type \c T in a ..Loc hierarchy, for which the inner +/// matcher matches on a another node of type \c T that can be reached using a +/// given traverse function. +template <typename T> +class TypeLocTraverseMatcher : public MatcherInterface<T> { +public: + explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher, + TypeLoc (T::*TraverseFunction)() const) + : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} + + virtual bool matches(const T &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + TypeLoc NextNode = (Node.*TraverseFunction)(); + if (!NextNode) + return false; + return InnerMatcher.matches(NextNode, Finder, Builder); + } + +private: + const Matcher<TypeLoc> InnerMatcher; + TypeLoc (T::*TraverseFunction)() const; +}; + +template <typename T, typename InnerT> +T makeTypeAllOfComposite(ArrayRef<const Matcher<InnerT> *> InnerMatchers) { + return T(makeAllOfComposite<InnerT>(InnerMatchers)); +} + } // end namespace internal } // end namespace ast_matchers } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h index c68534a..953abc2 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -221,4 +221,69 @@ const NodeType &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const +/// \brief Creates a variadic matcher for both a specific \c Type as well as +/// the corresponding \c TypeLoc. +#define AST_TYPE_MATCHER(NodeType, MatcherName) \ + const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName; \ + const internal::VariadicDynCastAllOfMatcher<TypeLoc, \ + NodeType##Loc> MatcherName##Loc + +/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines +/// the matcher \c MatcherName that can be used to traverse from one \c Type +/// to another. +/// +/// For a specific \c SpecificType, the traversal is done using +/// \c SpecificType::FunctionName. The existance of such a function determines +/// whether a corresponding matcher can be used on \c SpecificType. +#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) \ +class Polymorphic##MatcherName##TypeMatcher { \ +public: \ + Polymorphic##MatcherName##TypeMatcher( \ + const internal::Matcher<QualType> &InnerMatcher) \ + : InnerMatcher(InnerMatcher) {} \ + template <typename T> operator internal::Matcher<T>() { \ + return internal::Matcher<T>(new internal::TypeTraverseMatcher<T>( \ + InnerMatcher, &T::FunctionName)); \ + } \ +private: \ + const internal::Matcher<QualType> InnerMatcher; \ +}; \ +class Variadic##MatcherName##TypeTraverseMatcher \ + : public llvm::VariadicFunction< \ + Polymorphic##MatcherName##TypeMatcher, \ + internal::Matcher<QualType>, \ + internal::makeTypeAllOfComposite< \ + Polymorphic##MatcherName##TypeMatcher, QualType> > { \ +public: \ + Variadic##MatcherName##TypeTraverseMatcher() {} \ +}; \ +const Variadic##MatcherName##TypeTraverseMatcher MatcherName + +/// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works +/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. +#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) \ +class Polymorphic##MatcherName##TypeLocMatcher { \ +public: \ + Polymorphic##MatcherName##TypeLocMatcher( \ + const internal::Matcher<TypeLoc> &InnerMatcher) \ + : InnerMatcher(InnerMatcher) {} \ + template <typename T> operator internal::Matcher<T>() { \ + return internal::Matcher<T>(new internal::TypeLocTraverseMatcher<T>( \ + InnerMatcher, &T::FunctionName##Loc)); \ + } \ +private: \ + const internal::Matcher<TypeLoc> InnerMatcher; \ +}; \ +class Variadic##MatcherName##TypeLocTraverseMatcher \ + : public llvm::VariadicFunction< \ + Polymorphic##MatcherName##TypeLocMatcher, \ + internal::Matcher<TypeLoc>, \ + internal::makeTypeAllOfComposite< \ + Polymorphic##MatcherName##TypeLocMatcher, TypeLoc> > { \ +public: \ + Variadic##MatcherName##TypeLocTraverseMatcher() {} \ +}; \ +const Variadic##MatcherName##TypeLocTraverseMatcher MatcherName##Loc; \ +AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type) + #endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTTypeTraits.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTTypeTraits.h new file mode 100644 index 0000000..bda53ea --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTTypeTraits.h @@ -0,0 +1,209 @@ +//===--- ASTMatchersTypeTraits.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Provides a dynamically typed node container that can be used to store +// an AST base node at runtime in the same storage in a type safe way. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H +#define LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H + +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "llvm/Support/AlignOf.h" + +namespace clang { +namespace ast_type_traits { + +/// \brief A dynamically typed AST node container. +/// +/// Stores an AST node in a type safe way. This allows writing code that +/// works with different kinds of AST nodes, despite the fact that they don't +/// have a common base class. +/// +/// Use \c create(Node) to create a \c DynTypedNode from an AST node, +/// and \c get<T>() to retrieve the node as type T if the types match. +/// +/// See \c NodeTypeTag for which node base types are currently supported; +/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of +/// the supported base types. +class DynTypedNode { +public: + /// \brief Creates a \c DynTypedNode from \c Node. + template <typename T> + static DynTypedNode create(const T &Node) { + return BaseConverter<T>::create(Node); + } + + /// \brief Retrieve the stored node as type \c T. + /// + /// Returns NULL if the stored node does not have a type that is + /// convertible to \c T. + /// + /// For types that have identity via their pointer in the AST + /// (like \c Stmt and \c Decl) the returned pointer points to the + /// referenced AST node. + /// For other types (like \c QualType) the value is stored directly + /// in the \c DynTypedNode, and the returned pointer points at + /// the storage inside DynTypedNode. For those nodes, do not + /// use the pointer outside the scope of the DynTypedNode. + template <typename T> + const T *get() const { + return BaseConverter<T>::get(Tag, Storage.buffer); + } + + /// \brief Returns a pointer that identifies the stored AST node. + /// + /// Note that this is not supported by all AST nodes. For AST nodes + /// that don't have a pointer-defined identity inside the AST, this + /// method returns NULL. + const void *getMemoizationData() const; + +private: + /// \brief Takes care of converting from and to \c T. + template <typename T, typename EnablerT = void> struct BaseConverter; + + /// \brief Supported base node types. + enum NodeTypeTag { + NT_Decl, + NT_Stmt, + NT_NestedNameSpecifier, + NT_NestedNameSpecifierLoc, + NT_QualType, + NT_Type, + NT_TypeLoc + } Tag; + + /// \brief Stores the data of the node. + /// + /// Note that we can store \c Decls and \c Stmts by pointer as they are + /// guaranteed to be unique pointers pointing to dedicated storage in the + /// AST. \c QualTypes on the other hand do not have storage or unique + /// pointers and thus need to be stored by value. + llvm::AlignedCharArrayUnion<Decl*, QualType, TypeLoc, NestedNameSpecifierLoc> + Storage; +}; + +// FIXME: Pull out abstraction for the following. +template<typename T> struct DynTypedNode::BaseConverter<T, + typename llvm::enable_if<llvm::is_base_of<Decl, T> >::type> { + static const T *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_Decl) + return dyn_cast<T>(*reinterpret_cast<Decl*const*>(Storage)); + return NULL; + } + static DynTypedNode create(const Decl &Node) { + DynTypedNode Result; + Result.Tag = NT_Decl; + new (Result.Storage.buffer) const Decl*(&Node); + return Result; + } +}; +template<typename T> struct DynTypedNode::BaseConverter<T, + typename llvm::enable_if<llvm::is_base_of<Stmt, T> >::type> { + static const T *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_Stmt) + return dyn_cast<T>(*reinterpret_cast<Stmt*const*>(Storage)); + return NULL; + } + static DynTypedNode create(const Stmt &Node) { + DynTypedNode Result; + Result.Tag = NT_Stmt; + new (Result.Storage.buffer) const Stmt*(&Node); + return Result; + } +}; +template<typename T> struct DynTypedNode::BaseConverter<T, + typename llvm::enable_if<llvm::is_base_of<Type, T> >::type> { + static const T *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_Type) + return dyn_cast<T>(*reinterpret_cast<Type*const*>(Storage)); + return NULL; + } + static DynTypedNode create(const Type &Node) { + DynTypedNode Result; + Result.Tag = NT_Type; + new (Result.Storage.buffer) const Type*(&Node); + return Result; + } +}; +template<> struct DynTypedNode::BaseConverter<NestedNameSpecifier, void> { + static const NestedNameSpecifier *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_NestedNameSpecifier) + return *reinterpret_cast<NestedNameSpecifier*const*>(Storage); + return NULL; + } + static DynTypedNode create(const NestedNameSpecifier &Node) { + DynTypedNode Result; + Result.Tag = NT_NestedNameSpecifier; + new (Result.Storage.buffer) const NestedNameSpecifier*(&Node); + return Result; + } +}; +template<> struct DynTypedNode::BaseConverter<NestedNameSpecifierLoc, void> { + static const NestedNameSpecifierLoc *get(NodeTypeTag Tag, + const char Storage[]) { + if (Tag == NT_NestedNameSpecifierLoc) + return reinterpret_cast<const NestedNameSpecifierLoc*>(Storage); + return NULL; + } + static DynTypedNode create(const NestedNameSpecifierLoc &Node) { + DynTypedNode Result; + Result.Tag = NT_NestedNameSpecifierLoc; + new (Result.Storage.buffer) NestedNameSpecifierLoc(Node); + return Result; + } +}; +template<> struct DynTypedNode::BaseConverter<QualType, void> { + static const QualType *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_QualType) + return reinterpret_cast<const QualType*>(Storage); + return NULL; + } + static DynTypedNode create(const QualType &Node) { + DynTypedNode Result; + Result.Tag = NT_QualType; + new (Result.Storage.buffer) QualType(Node); + return Result; + } +}; +template<> struct DynTypedNode::BaseConverter<TypeLoc, void> { + static const TypeLoc *get(NodeTypeTag Tag, const char Storage[]) { + if (Tag == NT_TypeLoc) + return reinterpret_cast<const TypeLoc*>(Storage); + return NULL; + } + static DynTypedNode create(const TypeLoc &Node) { + DynTypedNode Result; + Result.Tag = NT_TypeLoc; + new (Result.Storage.buffer) TypeLoc(Node); + return Result; + } +}; +// The only operation we allow on unsupported types is \c get. +// This allows to conveniently use \c DynTypedNode when having an arbitrary +// AST node that is not supported, but prevents misuse - a user cannot create +// a DynTypedNode from arbitrary types. +template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter { + static const T *get(NodeTypeTag Tag, const char Storage[]) { return NULL; } +}; + +inline const void *DynTypedNode::getMemoizationData() const { + switch (Tag) { + case NT_Decl: return BaseConverter<Decl>::get(Tag, Storage.buffer); + case NT_Stmt: return BaseConverter<Stmt>::get(Tag, Storage.buffer); + default: return NULL; + }; +} + +} // end namespace ast_type_traits +} // end namespace clang + +#endif // LLVM_CLANG_AST_MATCHERS_AST_TYPE_TRAITS_H 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 b6291f4..73c2e61 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h @@ -23,6 +23,8 @@ namespace clang { +class TargetInfo; + //===----------------------------------------------------------------------===// /// Common components of both fprintf and fscanf format strings. namespace analyze_format_string { @@ -115,11 +117,14 @@ public: // C99 conversion specifiers. cArg, dArg, + DArg, // Apple extension iArg, - IntArgBeg = cArg, IntArgEnd = iArg, + IntArgBeg = dArg, IntArgEnd = iArg, oArg, + OArg, // Apple extension uArg, + UArg, // Apple extension xArg, XArg, UIntArgBeg = oArg, UIntArgEnd = XArg, @@ -148,9 +153,9 @@ public: ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg, // FreeBSD specific specifiers - bArg, - DArg, - rArg, + FreeBSDbArg, + FreeBSDDArg, + FreeBSDrArg, // GlibC specific specifiers. PrintErrno, // 'm' @@ -162,7 +167,7 @@ public: ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg }; - ConversionSpecifier(bool isPrintf) + ConversionSpecifier(bool isPrintf = true) : IsPrintf(isPrintf), Position(0), EndScanList(0), kind(InvalidSpecifier) {} ConversionSpecifier(bool isPrintf, const char *pos, Kind k) @@ -194,10 +199,14 @@ public: return EndScanList ? EndScanList - Position : 1; } + bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; } bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; } + bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; } const char *toString() const; bool isPrintfKind() const { return IsPrintf; } + + llvm::Optional<ConversionSpecifier> getStandardSpecifier() const; protected: bool IsPrintf; @@ -353,10 +362,12 @@ public: bool usesPositionalArg() const { return UsesPositionalArg; } - bool hasValidLengthModifier() const; + bool hasValidLengthModifier(const TargetInfo &Target) const; bool hasStandardLengthModifier() const; + llvm::Optional<LengthModifier> getCorrectedLengthModifier() const; + bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const; bool hasStandardLengthConversionCombination() const; @@ -383,7 +394,6 @@ public: : ConversionSpecifier(true, pos, k) {} bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; } - bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; } bool isDoubleArg() const { return kind >= DoubleArgBeg && kind <= DoubleArgEnd; } unsigned getLength() const { @@ -628,10 +638,12 @@ public: }; bool ParsePrintfString(FormatStringHandler &H, - const char *beg, const char *end, const LangOptions &LO); + const char *beg, const char *end, const LangOptions &LO, + const TargetInfo &Target); bool ParseScanfString(FormatStringHandler &H, - const char *beg, const char *end, const LangOptions &LO); + const char *beg, const char *end, const LangOptions &LO, + const TargetInfo &Target); } // end analyze_format_string namespace } // end clang namespace diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h index 742cc04..ef6b821 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h @@ -132,7 +132,8 @@ public: /// \param Loc -- The location of the protected operation. virtual void handleMutexNotHeld(const NamedDecl *D, ProtectedOperationKind POK, Name LockName, - LockKind LK, SourceLocation Loc) {} + LockKind LK, SourceLocation Loc, + Name *PossibleMatch=0) {} /// Warn when a function is called while an excluded mutex is locked. For /// example, the mutex may be locked inside the function. diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h index 46b4e93..5246678 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h @@ -72,7 +72,7 @@ class AnalysisDeclContext { /// AnalysisDeclContext. This may be null. AnalysisDeclContextManager *Manager; - const Decl *D; + const Decl * const D; OwningPtr<CFG> cfg, completeCFG; OwningPtr<CFGStmtMap> cfgStmtMap; @@ -81,9 +81,6 @@ class AnalysisDeclContext { CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs; bool builtCFG, builtCompleteCFG; - - OwningPtr<LiveVariables> liveness; - OwningPtr<LiveVariables> relaxedLiveness; OwningPtr<ParentMap> PM; OwningPtr<PseudoConstantAnalysis> PCA; OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA; @@ -104,9 +101,15 @@ public: ~AnalysisDeclContext(); - ASTContext &getASTContext() { return D->getASTContext(); } + ASTContext &getASTContext() const { return D->getASTContext(); } const Decl *getDecl() const { return D; } + /// Return the AnalysisDeclContextManager (if any) that created + /// this AnalysisDeclContext. + AnalysisDeclContextManager *getManager() const { + return Manager; + } + /// Return the build options used to construct the CFG. CFG::BuildOptions &getCFGBuildOptions() { return cfgBuildOptions; @@ -234,9 +237,10 @@ public: const StackFrameContext *getCurrentStackFrame() const; - virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; + /// Return true if the current LocationContext has no caller context. + virtual bool inTopFrame() const; - static bool classof(const LocationContext*) { return true; } + virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; public: static void ProfileCommon(llvm::FoldingSetNodeID &ID, @@ -270,6 +274,9 @@ public: const CFGBlock *getCallSiteBlock() const { return Block; } + /// Return true if the current LocationContext has no caller context. + virtual bool inTopFrame() const { return getParent() == 0; } + unsigned getIndex() const { return Index; } void Profile(llvm::FoldingSetNodeID &ID); @@ -379,11 +386,17 @@ class AnalysisDeclContextManager { ContextMap Contexts; LocationContextManager LocContexts; CFG::BuildOptions cfgBuildOptions; + + /// Flag to indicate whether or not bodies should be synthesized + /// for well-known functions. + bool SynthesizeBodies; public: AnalysisDeclContextManager(bool useUnoptimizedCFG = false, - bool addImplicitDtors = false, - bool addInitializers = false); + bool addImplicitDtors = false, + bool addInitializers = false, + bool addTemporaryDtors = false, + bool synthesizeBodies = false); ~AnalysisDeclContextManager(); @@ -396,6 +409,10 @@ public: CFG::BuildOptions &getCFGBuildOptions() { return cfgBuildOptions; } + + /// Return true if faux bodies should be synthesized for well-known + /// functions. + bool synthesizeBodies() const { return SynthesizeBodies; } const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx, LocationContext const *Parent, diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h index 4d087e7..8cc5d81 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h @@ -88,8 +88,6 @@ public: return static_cast<const ElemTy*>(this); return 0; } - - static bool classof(const CFGElement *E) { return true; } }; class CFGStmt : public CFGElement { @@ -568,6 +566,7 @@ public: bool AddEHEdges; bool AddInitializers; bool AddImplicitDtors; + bool AddTemporaryDtors; bool alwaysAdd(const Stmt *stmt) const { return alwaysAddMask[stmt->getStmtClass()]; @@ -587,7 +586,8 @@ public: : forcedBlkExprs(0), PruneTriviallyFalseEdges(true) ,AddEHEdges(false) ,AddInitializers(false) - ,AddImplicitDtors(false) {} + ,AddImplicitDtors(false) + ,AddTemporaryDtors(false) {} }; /// \brief Provides a custom implementation of the iterator class to have the diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h b/contrib/llvm/tools/clang/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h new file mode 100644 index 0000000..930c2bd --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h @@ -0,0 +1,46 @@ +//= ObjCNoReturn.h - Handling of Cocoa APIs known not to return --*- C++ -*---// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements special handling of recognizing ObjC API hooks that +// do not return but aren't marked as such in API headers. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_DS_OBJCNORETURN +#define LLVM_CLANG_ANALYSIS_DS_OBJCNORETURN + +#include "clang/Basic/IdentifierTable.h" + +namespace clang { + +class ASTContext; +class ObjCMessageExpr; + +class ObjCNoReturn { + /// Cached "raise" selector. + Selector RaiseSel; + + /// Cached identifier for "NSException". + IdentifierInfo *NSExceptionII; + + enum { NUM_RAISE_SELECTORS = 2 }; + + /// Cached set of selectors in NSException that are 'noreturn'. + Selector NSExceptionInstanceRaiseSelectors[NUM_RAISE_SELECTORS]; + +public: + ObjCNoReturn(ASTContext &C); + + /// Return true if the given message expression is known to never + /// return. + bool isImplicitNoReturn(const ObjCMessageExpr *ME); +}; +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h index 5de06cd..9479978 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h @@ -140,8 +140,6 @@ public: return ID.ComputeHash(); } - static bool classof(const ProgramPoint*) { return true; } - bool operator==(const ProgramPoint & RHS) const { return Data1 == RHS.Data1 && Data2 == RHS.Data2 && @@ -213,7 +211,9 @@ class StmtPoint : public ProgramPoint { public: StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, const ProgramPointTag *tag) - : ProgramPoint(S, p2, k, L, tag) {} + : ProgramPoint(S, p2, k, L, tag) { + assert(S); + } const Stmt *getStmt() const { return (const Stmt*) getData1(); } @@ -461,6 +461,7 @@ public: }; /// Represents a point when we begin processing an inlined call. +/// CallEnter uses the caller's location context. class CallEnter : public ProgramPoint { public: CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td index fade83e..bfe8093 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td @@ -190,7 +190,7 @@ def Availability : InheritableAttr { [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch<llvm::StringRef>(Platform) .Case("ios", "iOS") - .Case("macosx", "Mac OS X") + .Case("macosx", "OS X") .Default(llvm::StringRef()); } }]; } @@ -341,6 +341,11 @@ def Final : InheritableAttr { let SemaHandler = 0; } +def MinSize : InheritableAttr { + let Spellings = [GNU<"minsize">]; + let Subjects = [Function]; +} + def Format : InheritableAttr { let Spellings = [GNU<"format">]; let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">, @@ -528,6 +533,11 @@ def ObjCReturnsInnerPointer : Attr { let Subjects = [ObjCMethod]; } +def ObjCRequiresSuper : InheritableAttr { + let Spellings = [GNU<"objc_requires_super">]; + let Subjects = [ObjCMethod]; +} + def ObjCRootClass : Attr { let Spellings = [GNU<"objc_root_class">]; let Subjects = [ObjCInterface]; @@ -556,6 +566,10 @@ def Packed : InheritableAttr { let Spellings = [GNU<"packed">]; } +def PnaclCall : InheritableAttr { + let Spellings = [GNU<"pnaclcall">]; +} + def Pcs : InheritableAttr { let Spellings = [GNU<"pcs">]; let Args = [EnumArgument<"PCS", "PCSType", diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def index 84b2881..d48eadc 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def @@ -41,6 +41,7 @@ // J -> jmp_buf // SJ -> sigjmp_buf // K -> ucontext_t +// p -> pid_t // . -> "...". This may only occur at the end of the function list. // // Types may be prefixed with the following modifiers: @@ -388,6 +389,7 @@ BUILTIN(__builtin_popcountll, "iULLi", "nc") // FIXME: These type signatures are not correct for targets with int != 32-bits // or with ULL != 64-bits. +BUILTIN(__builtin_bswap16, "UsUs", "nc") BUILTIN(__builtin_bswap32, "UiUi", "nc") BUILTIN(__builtin_bswap64, "ULLiULLi", "nc") @@ -478,6 +480,7 @@ BUILTIN(__builtin_expect, "LiLiLi" , "nc") BUILTIN(__builtin_prefetch, "vvC*.", "nc") BUILTIN(__builtin_readcyclecounter, "ULLi", "n") BUILTIN(__builtin_trap, "v", "nr") +BUILTIN(__builtin_debugtrap, "v", "n") BUILTIN(__builtin_unreachable, "v", "nr") BUILTIN(__builtin_shufflevector, "v." , "nc") BUILTIN(__builtin_alloca, "v*z" , "n") @@ -735,7 +738,7 @@ LIBBUILTIN(strcasecmp, "icC*cC*", "f", "strings.h", ALL_LANGUAGES) LIBBUILTIN(strncasecmp, "icC*cC*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) +LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_LANGUAGES) // POSIX setjmp.h // In some systems setjmp is a macro that expands to _setjmp. We undefine @@ -826,9 +829,13 @@ LIBBUILTIN(atan2, "ddd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(atan2l, "LdLdLd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(atan2f, "fff", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(ceil, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(ceill, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(ceilf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(ceil, "dd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(ceill, "LdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(ceilf, "ff", "fc", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(copysign, "ddd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(copysignl, "LdLdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(copysignf, "fff", "fc", "math.h", ALL_LANGUAGES) LIBBUILTIN(cos, "dd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(cosl, "LdLd", "fe", "math.h", ALL_LANGUAGES) @@ -838,37 +845,53 @@ LIBBUILTIN(exp, "dd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(expl, "LdLd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(expf, "ff", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fabs, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fabsl, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fabsf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(exp2, "dd", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(exp2l, "LdLd", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(exp2f, "ff", "fe", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(fabs, "dd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fabsl, "LdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fabsf, "ff", "fc", "math.h", ALL_LANGUAGES) -LIBBUILTIN(floor, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(floorl, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(floorf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(floor, "dd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(floorl, "LdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(floorf, "ff", "fc", "math.h", ALL_LANGUAGES) LIBBUILTIN(fma, "dddd", "fc", "math.h", ALL_LANGUAGES) LIBBUILTIN(fmal, "LdLdLdLd", "fc", "math.h", ALL_LANGUAGES) LIBBUILTIN(fmaf, "ffff", "fc", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fmax, "ddd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fmaxl, "LdLdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fmaxf, "fff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmax, "ddd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmaxl, "LdLdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmaxf, "fff", "fc", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fmin, "ddd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fminl, "LdLdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(fminf, "fff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmin, "ddd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fminl, "LdLdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fminf, "fff", "fc", "math.h", ALL_LANGUAGES) LIBBUILTIN(log, "dd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(logl, "LdLd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(logf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(log2, "dd", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(log2l, "LdLd", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(log2f, "ff", "fe", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(nearbyint, "dd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nearbyintl, "LdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nearbyintf, "ff", "fc", "math.h", ALL_LANGUAGES) + LIBBUILTIN(pow, "ddd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(powl, "LdLdLd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(powf, "fff", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(round, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(roundl, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(roundf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(rint, "dd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(rintl, "LdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(rintf, "ff", "fc", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(round, "dd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(roundl, "LdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(roundf, "ff", "fc", "math.h", ALL_LANGUAGES) LIBBUILTIN(sin, "dd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(sinl, "LdLd", "fe", "math.h", ALL_LANGUAGES) @@ -882,6 +905,10 @@ LIBBUILTIN(tan, "dd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(tanl, "LdLd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(tanf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(trunc, "dd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(truncl, "LdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(truncf, "ff", "fc", "math.h", ALL_LANGUAGES) + // Blocks runtime Builtin math library functions LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES) LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES) diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsMips.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsMips.def index d013715..43fb907 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsMips.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsMips.def @@ -14,6 +14,8 @@ // The format of this database matches clang/Basic/Builtins.def. +// MIPS DSP Rev 1 + // Add/subtract with optional saturation BUILTIN(__builtin_mips_addu_qb, "V4ScV4ScV4Sc", "n") BUILTIN(__builtin_mips_addu_s_qb, "V4ScV4ScV4Sc", "n") @@ -122,4 +124,65 @@ BUILTIN(__builtin_mips_lbux, "iv*i", "n") BUILTIN(__builtin_mips_lhx, "iv*i", "n") BUILTIN(__builtin_mips_lwx, "iv*i", "n") +// MIPS DSP Rev 2 + +BUILTIN(__builtin_mips_absq_s_qb, "V4ScV4Sc", "n") + +BUILTIN(__builtin_mips_addqh_ph, "V2sV2sV2s", "nc") +BUILTIN(__builtin_mips_addqh_r_ph, "V2sV2sV2s", "nc") +BUILTIN(__builtin_mips_addqh_w, "iii", "nc") +BUILTIN(__builtin_mips_addqh_r_w, "iii", "nc") + +BUILTIN(__builtin_mips_addu_ph, "V2sV2sV2s", "n") +BUILTIN(__builtin_mips_addu_s_ph, "V2sV2sV2s", "n") + +BUILTIN(__builtin_mips_adduh_qb, "V4ScV4ScV4Sc", "nc") +BUILTIN(__builtin_mips_adduh_r_qb, "V4ScV4ScV4Sc", "nc") + +BUILTIN(__builtin_mips_append, "iiiIi", "nc") +BUILTIN(__builtin_mips_balign, "iiiIi", "nc") + +BUILTIN(__builtin_mips_cmpgdu_eq_qb, "iV4ScV4Sc", "n") +BUILTIN(__builtin_mips_cmpgdu_lt_qb, "iV4ScV4Sc", "n") +BUILTIN(__builtin_mips_cmpgdu_le_qb, "iV4ScV4Sc", "n") + +BUILTIN(__builtin_mips_dpa_w_ph, "LLiLLiV2sV2s", "nc") +BUILTIN(__builtin_mips_dps_w_ph, "LLiLLiV2sV2s", "nc") + +BUILTIN(__builtin_mips_dpaqx_s_w_ph, "LLiLLiV2sV2s", "n") +BUILTIN(__builtin_mips_dpaqx_sa_w_ph, "LLiLLiV2sV2s", "n") +BUILTIN(__builtin_mips_dpax_w_ph, "LLiLLiV2sV2s", "nc") +BUILTIN(__builtin_mips_dpsx_w_ph, "LLiLLiV2sV2s", "nc") +BUILTIN(__builtin_mips_dpsqx_s_w_ph, "LLiLLiV2sV2s", "n") +BUILTIN(__builtin_mips_dpsqx_sa_w_ph, "LLiLLiV2sV2s", "n") + +BUILTIN(__builtin_mips_mul_ph, "V2sV2sV2s", "n") +BUILTIN(__builtin_mips_mul_s_ph, "V2sV2sV2s", "n") + +BUILTIN(__builtin_mips_mulq_rs_w, "iii", "n") +BUILTIN(__builtin_mips_mulq_s_ph, "V2sV2sV2s", "n") +BUILTIN(__builtin_mips_mulq_s_w, "iii", "n") +BUILTIN(__builtin_mips_mulsa_w_ph, "LLiLLiV2sV2s", "nc") + +BUILTIN(__builtin_mips_precr_qb_ph, "V4ScV2sV2s", "n") +BUILTIN(__builtin_mips_precr_sra_ph_w, "V2siiIi", "nc") +BUILTIN(__builtin_mips_precr_sra_r_ph_w, "V2siiIi", "nc") + +BUILTIN(__builtin_mips_prepend, "iiiIi", "nc") + +BUILTIN(__builtin_mips_shra_qb, "V4ScV4Sci", "nc") +BUILTIN(__builtin_mips_shra_r_qb, "V4ScV4Sci", "nc") +BUILTIN(__builtin_mips_shrl_ph, "V2sV2si", "nc") + +BUILTIN(__builtin_mips_subqh_ph, "V2sV2sV2s", "nc") +BUILTIN(__builtin_mips_subqh_r_ph, "V2sV2sV2s", "nc") +BUILTIN(__builtin_mips_subqh_w, "iii", "nc") +BUILTIN(__builtin_mips_subqh_r_w, "iii", "nc") + +BUILTIN(__builtin_mips_subu_ph, "V2sV2sV2s", "n") +BUILTIN(__builtin_mips_subu_s_ph, "V2sV2sV2s", "n") + +BUILTIN(__builtin_mips_subuh_qb, "V4ScV4ScV4Sc", "nc") +BUILTIN(__builtin_mips_subuh_r_qb, "V4ScV4ScV4Sc", "nc") + #undef BUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def index f90a43f..3c3f06c 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def @@ -14,6 +14,7 @@ // The format of this database matches clang/Basic/Builtins.def. +// Builtins retained from previous PTX back-end BUILTIN(__builtin_ptx_read_tid_x, "i", "nc") BUILTIN(__builtin_ptx_read_tid_y, "i", "nc") BUILTIN(__builtin_ptx_read_tid_z, "i", "nc") @@ -59,4 +60,249 @@ BUILTIN(__builtin_ptx_read_pm3, "i", "n") BUILTIN(__builtin_ptx_bar_sync, "vi", "n") +// Builtins exposed as part of NVVM +BUILTIN(__syncthreads, "v", "n") +BUILTIN(__nvvm_bar0, "v", "n") +BUILTIN(__nvvm_bar0_popc, "ii", "n") +BUILTIN(__nvvm_bar0_and, "ii", "n") +BUILTIN(__nvvm_bar0_or, "ii", "n") +BUILTIN(__nvvm_membar_cta, "v", "n") +BUILTIN(__nvvm_membar_gl, "v", "n") +BUILTIN(__nvvm_membar_sys, "v", "n") +BUILTIN(__nvvm_popc_i, "ii", "nc") +BUILTIN(__nvvm_popc_ll, "LiLi", "nc") +BUILTIN(__nvvm_prmt, "UiUiUiUi", "nc") +BUILTIN(__nvvm_min_i, "iii", "nc") +BUILTIN(__nvvm_min_ui, "UiUiUi", "nc") +BUILTIN(__nvvm_min_ll, "LLiLLiLLi", "nc") +BUILTIN(__nvvm_min_ull, "ULLiULLiULLi", "nc") +BUILTIN(__nvvm_max_i, "iii", "nc") +BUILTIN(__nvvm_max_ui, "UiUiUi", "nc") +BUILTIN(__nvvm_max_ll, "LLiLLiLLi", "nc") +BUILTIN(__nvvm_max_ull, "ULLiULLiULLi", "nc") +BUILTIN(__nvvm_mulhi_i, "iii", "nc") +BUILTIN(__nvvm_mulhi_ui, "UiUiUi", "nc") +BUILTIN(__nvvm_mulhi_ll, "LLiLLiLLi", "nc") +BUILTIN(__nvvm_mulhi_ull, "ULLiULLiULLi", "nc") +BUILTIN(__nvvm_mul24_i, "iii", "nc") +BUILTIN(__nvvm_mul24_ui, "UiUiUi", "nc") +BUILTIN(__nvvm_brev32, "UiUi", "nc") +BUILTIN(__nvvm_brev64, "ULLiULLi", "nc") +BUILTIN(__nvvm_sad_i, "iiii", "nc") +BUILTIN(__nvvm_sad_ui, "UiUiUiUi", "nc") +BUILTIN(__nvvm_abs_i, "ii", "nc") +BUILTIN(__nvvm_abs_ll, "LiLi", "nc") +BUILTIN(__nvvm_floor_ftz_f, "ff", "nc") +BUILTIN(__nvvm_floor_f, "ff", "nc") +BUILTIN(__nvvm_floor_d, "dd", "nc") +BUILTIN(__nvvm_fabs_ftz_f, "ff", "nc") +BUILTIN(__nvvm_fabs_f, "ff", "nc") +BUILTIN(__nvvm_fabs_d, "dd", "nc") +BUILTIN(__nvvm_rcp_approx_ftz_d, "dd", "nc") +BUILTIN(__nvvm_fmin_ftz_f, "fff", "nc") +BUILTIN(__nvvm_fmin_f, "fff", "nc") +BUILTIN(__nvvm_fmax_ftz_f, "fff", "nc") +BUILTIN(__nvvm_fmax_f, "fff", "nc") +BUILTIN(__nvvm_rsqrt_approx_ftz_f, "ff", "nc") +BUILTIN(__nvvm_rsqrt_approx_f, "ff", "nc") +BUILTIN(__nvvm_fmin_d, "ddd", "nc") +BUILTIN(__nvvm_fmax_d, "ddd", "nc") +BUILTIN(__nvvm_rsqrt_approx_d, "dd", "nc") +BUILTIN(__nvvm_ceil_d, "dd", "nc") +BUILTIN(__nvvm_trunc_d, "dd", "nc") +BUILTIN(__nvvm_round_d, "dd", "nc") +BUILTIN(__nvvm_ex2_approx_d, "dd", "nc") +BUILTIN(__nvvm_lg2_approx_d, "dd", "nc") +BUILTIN(__nvvm_round_ftz_f, "ff", "nc") +BUILTIN(__nvvm_round_f, "ff", "nc") +BUILTIN(__nvvm_ex2_approx_ftz_f, "ff", "nc") +BUILTIN(__nvvm_ex2_approx_f, "ff", "nc") +BUILTIN(__nvvm_lg2_approx_ftz_f, "ff", "nc") +BUILTIN(__nvvm_lg2_approx_f, "ff", "nc") +BUILTIN(__nvvm_sin_approx_ftz_f, "ff", "nc") +BUILTIN(__nvvm_sin_approx_f, "ff", "nc") +BUILTIN(__nvvm_cos_approx_ftz_f, "ff", "nc") +BUILTIN(__nvvm_cos_approx_f, "ff", "nc") +BUILTIN(__nvvm_trunc_ftz_f, "ff", "nc") +BUILTIN(__nvvm_trunc_f, "ff", "nc") +BUILTIN(__nvvm_ceil_ftz_f, "ff", "nc") +BUILTIN(__nvvm_ceil_f, "ff", "nc") +BUILTIN(__nvvm_saturate_d, "dd", "nc") +BUILTIN(__nvvm_saturate_ftz_f, "ff", "nc") +BUILTIN(__nvvm_saturate_f, "ff", "nc") +BUILTIN(__nvvm_fma_rn_ftz_f, "ffff", "nc") +BUILTIN(__nvvm_fma_rn_f, "ffff", "nc") +BUILTIN(__nvvm_fma_rz_ftz_f, "ffff", "nc") +BUILTIN(__nvvm_fma_rz_f, "ffff", "nc") +BUILTIN(__nvvm_fma_rm_ftz_f, "ffff", "nc") +BUILTIN(__nvvm_fma_rm_f, "ffff", "nc") +BUILTIN(__nvvm_fma_rp_ftz_f, "ffff", "nc") +BUILTIN(__nvvm_fma_rp_f, "ffff", "nc") +BUILTIN(__nvvm_fma_rn_d, "dddd", "nc") +BUILTIN(__nvvm_fma_rz_d, "dddd", "nc") +BUILTIN(__nvvm_fma_rm_d, "dddd", "nc") +BUILTIN(__nvvm_fma_rp_d, "dddd", "nc") +BUILTIN(__nvvm_div_approx_ftz_f, "fff", "nc") +BUILTIN(__nvvm_div_approx_f, "fff", "nc") +BUILTIN(__nvvm_div_rn_ftz_f, "fff", "nc") +BUILTIN(__nvvm_div_rn_f, "fff", "nc") +BUILTIN(__nvvm_div_rz_ftz_f, "fff", "nc") +BUILTIN(__nvvm_div_rz_f, "fff", "nc") +BUILTIN(__nvvm_div_rm_ftz_f, "fff", "nc") +BUILTIN(__nvvm_div_rm_f, "fff", "nc") +BUILTIN(__nvvm_div_rp_ftz_f, "fff", "nc") +BUILTIN(__nvvm_div_rp_f, "fff", "nc") +BUILTIN(__nvvm_rcp_rn_ftz_f, "ff", "nc") +BUILTIN(__nvvm_rcp_rn_f, "ff", "nc") +BUILTIN(__nvvm_rcp_rz_ftz_f, "ff", "nc") +BUILTIN(__nvvm_rcp_rz_f, "ff", "nc") +BUILTIN(__nvvm_rcp_rm_ftz_f, "ff", "nc") +BUILTIN(__nvvm_rcp_rm_f, "ff", "nc") +BUILTIN(__nvvm_rcp_rp_ftz_f, "ff", "nc") +BUILTIN(__nvvm_rcp_rp_f, "ff", "nc") +BUILTIN(__nvvm_sqrt_rn_ftz_f, "ff", "nc") +BUILTIN(__nvvm_sqrt_rn_f, "ff", "nc") +BUILTIN(__nvvm_sqrt_rz_ftz_f, "ff", "nc") +BUILTIN(__nvvm_sqrt_rz_f, "ff", "nc") +BUILTIN(__nvvm_sqrt_rm_ftz_f, "ff", "nc") +BUILTIN(__nvvm_sqrt_rm_f, "ff", "nc") +BUILTIN(__nvvm_sqrt_rp_ftz_f, "ff", "nc") +BUILTIN(__nvvm_sqrt_rp_f, "ff", "nc") +BUILTIN(__nvvm_div_rn_d, "ddd", "nc") +BUILTIN(__nvvm_div_rz_d, "ddd", "nc") +BUILTIN(__nvvm_div_rm_d, "ddd", "nc") +BUILTIN(__nvvm_div_rp_d, "ddd", "nc") +BUILTIN(__nvvm_rcp_rn_d, "dd", "nc") +BUILTIN(__nvvm_rcp_rz_d, "dd", "nc") +BUILTIN(__nvvm_rcp_rm_d, "dd", "nc") +BUILTIN(__nvvm_rcp_rp_d, "dd", "nc") +BUILTIN(__nvvm_sqrt_rn_d, "dd", "nc") +BUILTIN(__nvvm_sqrt_rz_d, "dd", "nc") +BUILTIN(__nvvm_sqrt_rm_d, "dd", "nc") +BUILTIN(__nvvm_sqrt_rp_d, "dd", "nc") +BUILTIN(__nvvm_sqrt_approx_ftz_f, "ff", "nc") +BUILTIN(__nvvm_sqrt_approx_f, "ff", "nc") +BUILTIN(__nvvm_add_rn_d, "ddd", "nc") +BUILTIN(__nvvm_add_rz_d, "ddd", "nc") +BUILTIN(__nvvm_add_rm_d, "ddd", "nc") +BUILTIN(__nvvm_add_rp_d, "ddd", "nc") +BUILTIN(__nvvm_mul_rn_d, "ddd", "nc") +BUILTIN(__nvvm_mul_rz_d, "ddd", "nc") +BUILTIN(__nvvm_mul_rm_d, "ddd", "nc") +BUILTIN(__nvvm_mul_rp_d, "ddd", "nc") +BUILTIN(__nvvm_add_rm_ftz_f, "fff", "nc") +BUILTIN(__nvvm_add_rm_f, "fff", "nc") +BUILTIN(__nvvm_add_rp_ftz_f, "fff", "nc") +BUILTIN(__nvvm_add_rp_f, "fff", "nc") +BUILTIN(__nvvm_mul_rm_ftz_f, "fff", "nc") +BUILTIN(__nvvm_mul_rm_f, "fff", "nc") +BUILTIN(__nvvm_mul_rp_ftz_f, "fff", "nc") +BUILTIN(__nvvm_mul_rp_f, "fff", "nc") +BUILTIN(__nvvm_add_rn_ftz_f, "fff", "nc") +BUILTIN(__nvvm_add_rn_f, "fff", "nc") +BUILTIN(__nvvm_add_rz_ftz_f, "fff", "nc") +BUILTIN(__nvvm_add_rz_f, "fff", "nc") +BUILTIN(__nvvm_mul_rn_ftz_f, "fff", "nc") +BUILTIN(__nvvm_mul_rn_f, "fff", "nc") +BUILTIN(__nvvm_mul_rz_ftz_f, "fff", "nc") +BUILTIN(__nvvm_mul_rz_f, "fff", "nc") +BUILTIN(__nvvm_d2f_rn_ftz, "fd", "nc") +BUILTIN(__nvvm_d2f_rn, "fd", "nc") +BUILTIN(__nvvm_d2f_rz_ftz, "fd", "nc") +BUILTIN(__nvvm_d2f_rz, "fd", "nc") +BUILTIN(__nvvm_d2f_rm_ftz, "fd", "nc") +BUILTIN(__nvvm_d2f_rm, "fd", "nc") +BUILTIN(__nvvm_d2f_rp_ftz, "fd", "nc") +BUILTIN(__nvvm_d2f_rp, "fd", "nc") +BUILTIN(__nvvm_d2i_rn, "id", "nc") +BUILTIN(__nvvm_d2i_rz, "id", "nc") +BUILTIN(__nvvm_d2i_rm, "id", "nc") +BUILTIN(__nvvm_d2i_rp, "id", "nc") +BUILTIN(__nvvm_d2ui_rn, "Uid", "nc") +BUILTIN(__nvvm_d2ui_rz, "Uid", "nc") +BUILTIN(__nvvm_d2ui_rm, "Uid", "nc") +BUILTIN(__nvvm_d2ui_rp, "Uid", "nc") +BUILTIN(__nvvm_i2d_rn, "di", "nc") +BUILTIN(__nvvm_i2d_rz, "di", "nc") +BUILTIN(__nvvm_i2d_rm, "di", "nc") +BUILTIN(__nvvm_i2d_rp, "di", "nc") +BUILTIN(__nvvm_ui2d_rn, "dUi", "nc") +BUILTIN(__nvvm_ui2d_rz, "dUi", "nc") +BUILTIN(__nvvm_ui2d_rm, "dUi", "nc") +BUILTIN(__nvvm_ui2d_rp, "dUi", "nc") +BUILTIN(__nvvm_f2i_rn_ftz, "if", "nc") +BUILTIN(__nvvm_f2i_rn, "if", "nc") +BUILTIN(__nvvm_f2i_rz_ftz, "if", "nc") +BUILTIN(__nvvm_f2i_rz, "if", "nc") +BUILTIN(__nvvm_f2i_rm_ftz, "if", "nc") +BUILTIN(__nvvm_f2i_rm, "if", "nc") +BUILTIN(__nvvm_f2i_rp_ftz, "if", "nc") +BUILTIN(__nvvm_f2i_rp, "if", "nc") +BUILTIN(__nvvm_f2ui_rn_ftz, "Uif", "nc") +BUILTIN(__nvvm_f2ui_rn, "Uif", "nc") +BUILTIN(__nvvm_f2ui_rz_ftz, "Uif", "nc") +BUILTIN(__nvvm_f2ui_rz, "Uif", "nc") +BUILTIN(__nvvm_f2ui_rm_ftz, "Uif", "nc") +BUILTIN(__nvvm_f2ui_rm, "Uif", "nc") +BUILTIN(__nvvm_f2ui_rp_ftz, "Uif", "nc") +BUILTIN(__nvvm_f2ui_rp, "Uif", "nc") +BUILTIN(__nvvm_i2f_rn, "fi", "nc") +BUILTIN(__nvvm_i2f_rz, "fi", "nc") +BUILTIN(__nvvm_i2f_rm, "fi", "nc") +BUILTIN(__nvvm_i2f_rp, "fi", "nc") +BUILTIN(__nvvm_ui2f_rn, "fUi", "nc") +BUILTIN(__nvvm_ui2f_rz, "fUi", "nc") +BUILTIN(__nvvm_ui2f_rm, "fUi", "nc") +BUILTIN(__nvvm_ui2f_rp, "fUi", "nc") +BUILTIN(__nvvm_lohi_i2d, "dii", "nc") +BUILTIN(__nvvm_d2i_lo, "id", "nc") +BUILTIN(__nvvm_d2i_hi, "id", "nc") +BUILTIN(__nvvm_f2ll_rn_ftz, "LLif", "nc") +BUILTIN(__nvvm_f2ll_rn, "LLif", "nc") +BUILTIN(__nvvm_f2ll_rz_ftz, "LLif", "nc") +BUILTIN(__nvvm_f2ll_rz, "LLif", "nc") +BUILTIN(__nvvm_f2ll_rm_ftz, "LLif", "nc") +BUILTIN(__nvvm_f2ll_rm, "LLif", "nc") +BUILTIN(__nvvm_f2ll_rp_ftz, "LLif", "nc") +BUILTIN(__nvvm_f2ll_rp, "LLif", "nc") +BUILTIN(__nvvm_f2ull_rn_ftz, "ULLif", "nc") +BUILTIN(__nvvm_f2ull_rn, "ULLif", "nc") +BUILTIN(__nvvm_f2ull_rz_ftz, "ULLif", "nc") +BUILTIN(__nvvm_f2ull_rz, "ULLif", "nc") +BUILTIN(__nvvm_f2ull_rm_ftz, "ULLif", "nc") +BUILTIN(__nvvm_f2ull_rm, "ULLif", "nc") +BUILTIN(__nvvm_f2ull_rp_ftz, "ULLif", "nc") +BUILTIN(__nvvm_f2ull_rp, "ULLif", "nc") +BUILTIN(__nvvm_d2ll_rn, "LLid", "nc") +BUILTIN(__nvvm_d2ll_rz, "LLid", "nc") +BUILTIN(__nvvm_d2ll_rm, "LLid", "nc") +BUILTIN(__nvvm_d2ll_rp, "LLid", "nc") +BUILTIN(__nvvm_d2ull_rn, "ULLid", "nc") +BUILTIN(__nvvm_d2ull_rz, "ULLid", "nc") +BUILTIN(__nvvm_d2ull_rm, "ULLid", "nc") +BUILTIN(__nvvm_d2ull_rp, "ULLid", "nc") +BUILTIN(__nvvm_ll2f_rn, "fLLi", "nc") +BUILTIN(__nvvm_ll2f_rz, "fLLi", "nc") +BUILTIN(__nvvm_ll2f_rm, "fLLi", "nc") +BUILTIN(__nvvm_ll2f_rp, "fLLi", "nc") +BUILTIN(__nvvm_ull2f_rn, "fULLi", "nc") +BUILTIN(__nvvm_ull2f_rz, "fULLi", "nc") +BUILTIN(__nvvm_ull2f_rm, "fULLi", "nc") +BUILTIN(__nvvm_ull2f_rp, "fULLi", "nc") +BUILTIN(__nvvm_ll2d_rn, "dLLi", "nc") +BUILTIN(__nvvm_ll2d_rz, "dLLi", "nc") +BUILTIN(__nvvm_ll2d_rm, "dLLi", "nc") +BUILTIN(__nvvm_ll2d_rp, "dLLi", "nc") +BUILTIN(__nvvm_ull2d_rn, "dULLi", "nc") +BUILTIN(__nvvm_ull2d_rz, "dULLi", "nc") +BUILTIN(__nvvm_ull2d_rm, "dULLi", "nc") +BUILTIN(__nvvm_ull2d_rp, "dULLi", "nc") +BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "nc") +BUILTIN(__nvvm_f2h_rn, "Usf", "nc") +BUILTIN(__nvvm_h2f, "fUs", "nc") +BUILTIN(__nvvm_bitcast_i2f, "fi", "nc") +BUILTIN(__nvvm_bitcast_f2i, "if", "nc") +BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "nc") +BUILTIN(__nvvm_bitcast_d2ll, "LLid", "nc") + #undef BUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def index 75e6074..5b46f8e 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def @@ -613,6 +613,12 @@ BUILTIN(__builtin_ia32_gatherd_d256, "V8iV8iV8iC*V8iV8iIc", "") BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iV4iC*V2LLiV4iIc", "") BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iV4iC*V4LLiV4iIc", "") +// F16C +BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "") +BUILTIN(__builtin_ia32_vcvtps2ph256, "V8sV8fIi", "") +BUILTIN(__builtin_ia32_vcvtph2ps, "V4fV8s", "") +BUILTIN(__builtin_ia32_vcvtph2ps256, "V8fV8s", "") + // RDRAND BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "") BUILTIN(__builtin_ia32_rdrand32_step, "UiUi*", "") @@ -730,5 +736,8 @@ BUILTIN(__builtin_ia32_vfrczps, "V4fV4f", "") BUILTIN(__builtin_ia32_vfrczpd, "V2dV2d", "") BUILTIN(__builtin_ia32_vfrczps256, "V8fV8f", "") BUILTIN(__builtin_ia32_vfrczpd256, "V4dV4d", "") +BUILTIN(__builtin_ia32_xbegin, "i", "") +BUILTIN(__builtin_ia32_xend, "v", "") +BUILTIN(__builtin_ia32_xabort, "vIc", "") #undef BUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h b/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h index e7cfa8a..cdc4269 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/ConvertUTF.h @@ -147,7 +147,6 @@ ConversionResult ConvertUTF32toUTF8 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); -#ifdef CLANG_NEEDS_THESE_ONE_DAY ConversionResult ConvertUTF16toUTF32 ( const UTF16** sourceStart, const UTF16* sourceEnd, UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); @@ -159,7 +158,9 @@ ConversionResult ConvertUTF32toUTF16 ( Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); -Boolean isLegalUTF8String(const UTF8 *source, const UTF8 *sourceEnd); +Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd); + +unsigned getNumBytesForUTF8(UTF8 firstByte); #ifdef __cplusplus } @@ -175,11 +176,13 @@ namespace clang { * Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on * WideCharWidth. The converted data is written to ResultPtr, which needs to * point to at least WideCharWidth * (Source.Size() + 1) bytes. On success, - * ResultPtr will point one after the end of the copied string. + * ResultPtr will point one after the end of the copied string. On failure, + * ResultPtr will not be changed, and ErrorPtr will be set to the location of + * the first character which could not be converted. * \return true on success. */ bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source, - char *&ResultPtr); + char *&ResultPtr, const UTF8 *&ErrorPtr); /** * Convert an Unicode code point to UTF8 sequence. @@ -194,7 +197,6 @@ bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source, bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr); } -#endif #endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h index 3997fb8..e47f3e1 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 @@ #define LLVM_CLANG_DIAGNOSTIC_H #include "clang/Basic/DiagnosticIDs.h" +#include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -29,6 +30,7 @@ namespace clang { class DiagnosticConsumer; class DiagnosticBuilder; + class DiagnosticOptions; class IdentifierInfo; class DeclContext; class LangOptions; @@ -160,13 +162,6 @@ public: ak_qualtype_pair ///< pair<QualType, QualType> }; - /// \brief Specifies which overload candidates to display when overload - /// resolution fails. - enum OverloadsShown { - Ovl_All, ///< Show all overloads. - Ovl_Best ///< Show just the "best" overload candidates. - }; - /// \brief Represents on argument value, which is a union discriminated /// by ArgumentKind, with a value. typedef std::pair<ArgumentKind, intptr_t> ArgumentValue; @@ -190,6 +185,7 @@ private: // backtrace stack, 0 -> no limit. ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors? IntrusiveRefCntPtr<DiagnosticIDs> Diags; + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; DiagnosticConsumer *Client; bool OwnsDiagClient; SourceManager *SourceMgr; @@ -341,6 +337,7 @@ private: public: explicit DiagnosticsEngine( const IntrusiveRefCntPtr<DiagnosticIDs> &Diags, + DiagnosticOptions *DiagOpts, DiagnosticConsumer *client = 0, bool ShouldOwnClient = true); ~DiagnosticsEngine(); @@ -349,6 +346,9 @@ public: return Diags; } + /// \brief Retrieve the diagnostic options. + DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; } + DiagnosticConsumer *getClient() { return Client; } const DiagnosticConsumer *getClient() const { return Client; } @@ -478,10 +478,13 @@ public: } OverloadsShown getShowOverloads() const { return ShowOverloads; } - /// \brief Pretend that the last diagnostic issued was ignored. + /// \brief Pretend that the last diagnostic issued was ignored, so any + /// subsequent notes will be suppressed. /// /// This can be used by clients who suppress diagnostics themselves. void setLastDiagnosticIgnored() { + if (LastDiagLevel == DiagnosticIDs::Fatal) + FatalErrorOccurred = true; LastDiagLevel = DiagnosticIDs::Ignored; } @@ -584,7 +587,7 @@ public: const char *Argument, unsigned ArgLen, const ArgumentValue *PrevArgs, unsigned NumPrevArgs, SmallVectorImpl<char> &Output, - SmallVectorImpl<intptr_t> &QualTypeVals) const { + ArrayRef<intptr_t> QualTypeVals) const { ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, PrevArgs, NumPrevArgs, Output, ArgToStringCookie, QualTypeVals); @@ -837,7 +840,7 @@ class DiagnosticBuilder { /// call to ForceEmit. mutable bool IsForceEmit; - void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT + void operator=(const DiagnosticBuilder &) LLVM_DELETED_FUNCTION; friend class DiagnosticsEngine; DiagnosticBuilder() @@ -961,6 +964,10 @@ public: "Too many arguments to diagnostic!"); DiagObj->DiagFixItHints[NumFixits++] = Hint; } + + bool hasMaxRanges() const { + return NumRanges == DiagnosticsEngine::MaxRanges; + } }; inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td index 9cfe5ef..d869c99 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -137,7 +137,7 @@ def err_odr_function_type_inconsistent : Error< def warn_odr_tag_type_inconsistent : Warning< "type %0 has incompatible definitions in different translation units">; def note_odr_tag_kind_here: Note< - "%0 is a %select{struct|union|class|enum}1 here">; + "%0 is a %select{struct|interface|union|class|enum}1 here">; def note_odr_field : Note<"field %0 has type %1 here">; def note_odr_missing_field : Note<"no corresponding field here">; def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommentKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommentKinds.td index 235ca79..e6dfe5b 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommentKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommentKinds.td @@ -121,5 +121,21 @@ def warn_doc_returns_attached_to_a_void_function : Warning< "method returning void}1">, InGroup<Documentation>, DefaultIgnore; +// \deprecated command + +def warn_doc_deprecated_not_sync : Warning< + "declaration is marked with '\\deprecated' command but does not have " + "a deprecation attribute">, + InGroup<DocumentationDeprecatedSync>, DefaultIgnore; + +def note_add_deprecation_attr : Note< + "add a deprecation attribute to the declaration to silence this warning">; + +// verbatim block commands + +def warn_verbatim_block_end_without_start : Warning< + "'\\%0' command does not terminate a verbatim text block">, + InGroup<Documentation>, DefaultIgnore; + } // end of documentation issue category } // end of AST component diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td index f859287..a6ce9d4 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -78,9 +78,12 @@ def note_decl_hiding_tag_type : Note< "%1 %0 is hidden by a non-type declaration of %0 here">; // Sema && Lex -def ext_longlong : Extension< +def ext_c99_longlong : Extension< "'long long' is an extension when C99 mode is not enabled">, InGroup<LongLong>; +def ext_cxx11_longlong : Extension< + "'long long' is a C++11 extension">, + InGroup<CXX11LongLong>; def warn_cxx98_compat_longlong : Warning< "'long long' is incompatible with C++98">, InGroup<CXX98CompatPedantic>, DefaultIgnore; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td index 583b234..4b43035 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -11,6 +11,8 @@ let Component = "Driver" in { def err_drv_no_such_file : Error<"no such file or directory: '%0'">; def err_drv_unsupported_opt : Error<"unsupported option '%0'">; +def err_drv_unsupported_opt_for_target : Error< + "unsupported option '%0' for target '%1'">; def err_drv_unsupported_option_argument : Error< "unsupported argument '%1' to option '%0'">; def err_drv_unknown_stdin_type : Error< @@ -91,10 +93,10 @@ def err_drv_invalid_arch_for_deployment_target : Error< "invalid architecture '%0' for deployment target '%1'">; def err_drv_objc_gc_arr : Error< "cannot specify both '-fobjc-arc' and '%0'">; -def err_arc_nonfragile_abi : Error< - "-fobjc-arc is not supported with legacy abi">; -def err_arc_unsupported : Error< - "-fobjc-arc is not supported on current deployment target">; +def err_arc_unsupported_on_runtime : Error< + "-fobjc-arc is not supported on platforms using the legacy runtime">; +def err_arc_unsupported_on_toolchain : Error< // feel free to generalize this + "-fobjc-arc is not supported on versions of OS X prior to 10.6">; def err_drv_mg_requires_m_or_mm : Error< "option '-MG' requires '-M' or '-MM'">; def err_drv_asan_android_requires_pie : Error< @@ -119,14 +121,10 @@ def warn_drv_unused_argument : Warning< def warn_drv_empty_joined_argument : Warning< "joined argument expects additional value: '%0'">, InGroup<DiagGroup<"unused-command-line-argument">>; -def warn_drv_not_using_clang_cpp : Warning< - "not using the clang preprocessor due to user override">; -def warn_drv_not_using_clang_cxx : Warning< - "not using the clang compiler for C++ inputs">; -def warn_drv_not_using_clang_arch : Warning< - "not using the clang compiler for the '%0' architecture">; def warn_drv_clang_unsupported : Warning< "the clang compiler does not support '%0'">; +def warn_drv_deprecated_arg : Warning< + "argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>; def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; def warn_ignoring_ftabstop_value : Warning< @@ -141,5 +139,9 @@ def warn_drv_pch_not_first_include : Warning< def note_drv_command_failed_diag_msg : Note< "diagnostic msg: %0">; - + +def err_analyzer_config_no_value : Error< + "analyzer-config option '%0' has a key but no value">; +def err_analyzer_config_multiple_values : Error< + "analyzer-config option '%0' should contain only one '='">; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 417a22c..b7a8476 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -58,6 +58,8 @@ def warn_fe_cc_print_header_failure : Warning< "unable to open CC_PRINT_HEADERS file: %0 (using stderr)">; def warn_fe_cc_log_diagnostics_failure : Warning< "unable to open CC_LOG_DIAGNOSTICS file: %0 (using stderr)">; +def err_fe_no_pch_in_dir : Error< + "no suitable precompiled header file found in directory '%0'">; def warn_fe_serialized_diag_failure : Warning< "unable to open file %0 for serializing diagnostics (%1)">, @@ -76,6 +78,11 @@ def err_verify_invalid_content : Error< def err_verify_inconsistent_diags : Error< "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: " "%2">; +def err_verify_invalid_no_diags : Error< + "%select{expected|'expected-no-diagnostics'}0 directive cannot follow " + "%select{'expected-no-diagnostics' directive|other expected directives}0">; +def err_verify_no_directives : Error< + "no expected directives found: consider use of 'expected-no-diagnostics'">; def note_fixit_applied : Note<"FIX-IT applied suggested code changes">; def note_fixit_in_macro : Note< diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td index d8632dd..f9f9ec7 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td @@ -22,8 +22,6 @@ def : DiagGroup<"address">; def AddressOfTemporary : DiagGroup<"address-of-temporary">; def : DiagGroup<"aggregate-return">; def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">; -def : DiagGroup<"attributes">; -def : DiagGroup<"bad-function-cast">; def Availability : DiagGroup<"availability">; def Section : DiagGroup<"section">; def AutoImport : DiagGroup<"auto-import">; @@ -33,8 +31,11 @@ def StringConversion : DiagGroup<"string-conversion">; def SignConversion : DiagGroup<"sign-conversion">; def BoolConversion : DiagGroup<"bool-conversion">; def IntConversion : DiagGroup<"int-conversion">; +def EnumConversion : DiagGroup<"enum-conversion">; def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">; def NullConversion : DiagGroup<"null-conversion">; +def ImplicitConversionFloatingPointToBool : + DiagGroup<"implicit-conversion-floating-point-to-bool">; def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">; def CXXCompat: DiagGroup<"c++-compat">; def CastAlign : DiagGroup<"cast-align">; @@ -42,11 +43,11 @@ def : DiagGroup<"cast-qual">; def : DiagGroup<"char-align">; def Comment : DiagGroup<"comment">; def : DiagGroup<"ctor-dtor-privacy">; -def : DiagGroup<"declaration-after-statement">; def DefaultArgSpecialMember : DiagGroup<"default-arg-special-member">; def GNUDesignator : DiagGroup<"gnu-designator">; def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">; +def AbstractFinalClass : DiagGroup<"abstract-final-class">; def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings">; @@ -58,9 +59,14 @@ def DeprecatedImplementations :DiagGroup<"deprecated-implementations">; def : DiagGroup<"disabled-optimization">; def : DiagGroup<"discard-qual">; def : DiagGroup<"div-by-zero">; + def DocumentationHTML : DiagGroup<"documentation-html">; def DocumentationPedantic : DiagGroup<"documentation-pedantic">; -def Documentation : DiagGroup<"documentation", [DocumentationHTML]>; +def DocumentationDeprecatedSync : DiagGroup<"documentation-deprecated-sync">; +def Documentation : DiagGroup<"documentation", + [DocumentationHTML, + DocumentationDeprecatedSync]>; + def EmptyBody : DiagGroup<"empty-body">; def ExtraTokens : DiagGroup<"extra-tokens">; def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">; @@ -108,9 +114,9 @@ def ExitTimeDestructors : DiagGroup<"exit-time-destructors">; def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">; def FourByteMultiChar : DiagGroup<"four-char-constants">; def GlobalConstructors : DiagGroup<"global-constructors">; -def : DiagGroup<"idiomatic-parentheses">; def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">; def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">; +def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">; def DanglingElse: DiagGroup<"dangling-else">; def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">; def : DiagGroup<"import">; @@ -119,7 +125,6 @@ def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">; def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">; 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", @@ -131,11 +136,12 @@ def MissingBraces : DiagGroup<"missing-braces">; def MissingDeclarations: DiagGroup<"missing-declarations">; def : DiagGroup<"missing-format-attribute">; def : DiagGroup<"missing-include-dirs">; -def : DiagGroup<"missing-noreturn">; def MultiChar : DiagGroup<"multichar">; def : DiagGroup<"nested-externs">; -def : DiagGroup<"newline-eof">; -def LongLong : DiagGroup<"long-long">; +def CXX11LongLong : DiagGroup<"c++11-long-long">; +def LongLong : DiagGroup<"long-long", [CXX11LongLong]>; +def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">; +def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">; def MismatchedTags : DiagGroup<"mismatched-tags">; def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; def ModuleBuild : DiagGroup<"module-build">; @@ -157,6 +163,7 @@ def OverlengthStrings : DiagGroup<"overlength-strings">; def OverloadedVirtual : DiagGroup<"overloaded-virtual">; def PrivateExtern : DiagGroup<"private-extern">; def SelTypeCast : DiagGroup<"cast-of-sel-type">; +def BadFunctionCast : DiagGroup<"bad-function-cast">; def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">; def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">; def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">; @@ -183,7 +190,7 @@ 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">; +def Shorten64To32 : DiagGroup<"shorten-64-to-32">; def : DiagGroup<"sign-promo">; def SignCompare : DiagGroup<"sign-compare">; def : DiagGroup<"stack-protector">; @@ -192,11 +199,15 @@ def : DiagGroup<"synth">; def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">; def StringPlusInt : DiagGroup<"string-plus-int">; def StrncatSize : DiagGroup<"strncat-size">; -def TautologicalCompare : DiagGroup<"tautological-compare">; +def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">; +def TautologicalCompare : DiagGroup<"tautological-compare", + [TautologicalOutOfRangeCompare]>; def HeaderHygiene : DiagGroup<"header-hygiene">; +def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">; +def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">; // Preprocessor warnings. -def : DiagGroup<"builtin-macro-redefined">; +def AmbiguousMacro : DiagGroup<"ambiguous-macro">; // Just silence warnings about -Wstrict-aliasing for now. def : DiagGroup<"strict-aliasing=0">; @@ -262,26 +273,29 @@ def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">; def CustomAtomic : DiagGroup<"custom-atomic-properties">; def AtomicProperties : DiagGroup<"atomic-properties", [ImplicitAtomic, CustomAtomic]>; -def AutomaticReferenceCountingABI : DiagGroup<"arc-abi">; +// FIXME: Remove arc-abi once an Xcode is released that doesn't pass this flag. +def : DiagGroup<"arc-abi">; def ARCUnsafeRetainedAssign : DiagGroup<"arc-unsafe-retained-assign">; def ARCRetainCycles : DiagGroup<"arc-retain-cycles">; def ARCNonPodMemAccess : DiagGroup<"arc-non-pod-memaccess">; def AutomaticReferenceCounting : DiagGroup<"arc", - [AutomaticReferenceCountingABI, - ARCUnsafeRetainedAssign, + [ARCUnsafeRetainedAssign, ARCRetainCycles, ARCNonPodMemAccess]>; +def ARCRepeatedUseOfWeakMaybe : DiagGroup<"arc-maybe-repeated-use-of-weak">; +def ARCRepeatedUseOfWeak : DiagGroup<"arc-repeated-use-of-weak", + [ARCRepeatedUseOfWeakMaybe]>; def Selector : DiagGroup<"selector">; 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 VectorConversion : DiagGroup<"vector-conversion">; // clang specific def VexingParse : DiagGroup<"vexing-parse">; def VLA : DiagGroup<"vla">; def VolatileRegisterVar : DiagGroup<"volatile-register-var">; def Visibility : DiagGroup<"visibility">; +def ZeroLengthArray : DiagGroup<"zero-length-array">; // GCC calls -Wdeprecated-writable-strings -Wwrite-strings. def GCCWriteStrings : DiagGroup<"write-strings" , [DeprecatedWritableStr]>; @@ -300,6 +314,7 @@ def ParenthesesOnEquality : DiagGroup<"parentheses-equality">; def Parentheses : DiagGroup<"parentheses", [LogicalOpParentheses, BitwiseOpParentheses, + ShiftOpParentheses, ParenthesesOnEquality, DanglingElse]>; @@ -311,15 +326,16 @@ def Parentheses : DiagGroup<"parentheses", // - bool-to-pointer conversion warnings are on by default // - __null-to-integer conversion warnings are on by default def Conversion : DiagGroup<"conversion", - [DiagGroup<"shorten-64-to-32">, + [BoolConversion, ConstantConversion, + EnumConversion, + Shorten64To32, + IntConversion, LiteralConversion, - StringConversion, - SignConversion, - BoolConversion, - NullConversion, // NULL->non-pointer NonLiteralNullConversion, // (1-1)->pointer (etc) - IntConversion]>, + NullConversion, // NULL->non-pointer + SignConversion, + StringConversion]>, DiagCategory<"Value Conversion Issue">; def Unused : DiagGroup<"unused", @@ -345,6 +361,8 @@ def Format2 : DiagGroup<"format=2", def TypeSafety : DiagGroup<"type-safety">; +def IntToPointerCast : DiagGroup<"int-to-pointer-cast">; + def Extra : DiagGroup<"extra", [ MissingFieldInitializers, IgnoredQualifiers, @@ -361,6 +379,7 @@ def Most : DiagGroup<"most", [ DeleteNonVirtualDtor, Format, Implicit, + IntToPointerCast, MismatchedTags, MissingBraces, MultiChar, @@ -382,9 +401,12 @@ def Most : DiagGroup<"most", [ // Thread Safety warnings def ThreadSafetyAttributes : DiagGroup<"thread-safety-attributes">; -def ThreadSafetyAnalysis : DiagGroup<"thread-safety-analysis">; -def ThreadSafety : DiagGroup<"thread-safety", - [ThreadSafetyAttributes, ThreadSafetyAnalysis]>; +def ThreadSafetyAnalysis : DiagGroup<"thread-safety-analysis">; +def ThreadSafetyPrecise : DiagGroup<"thread-safety-precise">; +def ThreadSafety : DiagGroup<"thread-safety", + [ThreadSafetyAttributes, + ThreadSafetyAnalysis, + ThreadSafetyPrecise]>; // Note that putting warnings in -Wall will not disable them by default. If a // warning should be active _only_ when -Wall is passed in, mark it as @@ -414,7 +436,8 @@ def NonGCC : DiagGroup<"non-gcc", // A warning group for warnings about using C++11 features as extensions in // earlier C++ versions. -def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi]>; +def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11LongLong]>; + def : DiagGroup<"c++0x-extensions", [CXX11]>; def DelegatingCtorCycles : DiagGroup<"delegating-ctor-cycles">; @@ -426,7 +449,7 @@ def C11 : DiagGroup<"c11-extensions">; def C99 : DiagGroup<"c99-extensions">; // A warning group for warnings about GCC extensions. -def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>; +def GNU : DiagGroup<"gnu", [GNUDesignator, VLA, ZeroLengthArray]>; // A warning group for warnings about code that clang accepts but gcc doesn't. def GccCompat : DiagGroup<"gcc-compat">; @@ -451,3 +474,9 @@ def ObjCStringComparison : DiagGroup<"objc-string-compare">; def ObjCLiteralComparison : DiagGroup<"objc-literal-compare", [ ObjCStringComparison ]>; + +// Inline ASM warnings. +def ASMOperandWidths : DiagGroup<"asm-operand-widths">; +def ASM : DiagGroup<"asm", [ + ASMOperandWidths + ]>; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td index cc958db..c6c50ab 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -41,9 +41,9 @@ def trigraph_ends_block_comment : Warning<"trigraph ends block comment">, def trigraph_converted : Warning<"trigraph converted to '%0' character">, InGroup<Trigraphs>; -def ext_multi_line_bcpl_comment : Extension<"multi-line // comment">, +def ext_multi_line_line_comment : Extension<"multi-line // comment">, InGroup<Comment>; -def ext_bcpl_comment : Extension< +def ext_line_comment : Extension< "// comments are not allowed in this language">, InGroup<Comment>; def ext_no_newline_eof : Extension<"no newline at end of file">, @@ -55,7 +55,7 @@ def warn_cxx98_compat_no_newline_eof : Warning< def ext_dollar_in_identifier : Extension<"'$' in identifier">, InGroup<DiagGroup<"dollar-in-identifier-extension">>; -def ext_charize_microsoft : Extension<"@# is a microsoft extension">, +def ext_charize_microsoft : Extension<"charizing operator #@ is a Microsoft extension">, InGroup<Microsoft>; def ext_token_used : Extension<"extension used">, @@ -127,15 +127,16 @@ def warn_char_constant_too_large : Warning< def err_multichar_utf_character_literal : Error< "Unicode character literals may not contain multiple characters">; def err_exponent_has_no_digits : Error<"exponent has no digits">; -def ext_imaginary_constant : Extension<"imaginary constants are an extension">; +def ext_imaginary_constant : Extension< + "imaginary constants are a GNU extension">, InGroup<GNU>; def err_hexconstant_requires_exponent : Error< "hexadecimal floating constants require an exponent">; def err_hexconstant_requires_digits : Error< "hexadecimal floating constants require a significand">; def ext_hexconstant_invalid : Extension< - "hexadecimal floating constants are a C99 feature">; + "hexadecimal floating constants are a C99 feature">, InGroup<C99>; def ext_binary_literal : Extension< - "binary integer literals are an extension">; + "binary integer literals are a GNU extension">, InGroup<GNU>; def err_pascal_string_too_long : Error<"Pascal string is too long">; def warn_octal_escape_too_large : ExtWarn<"octal escape sequence out of range">; def warn_hex_escape_too_large : ExtWarn<"hex escape sequence out of range">; @@ -228,6 +229,12 @@ def pp_macro_not_used : Warning<"macro is not used">, DefaultIgnore, def warn_pp_undef_identifier : Warning< "%0 is not defined, evaluates to 0">, InGroup<DiagGroup<"undef">>, DefaultIgnore; +def warn_pp_ambiguous_macro : Warning< + "ambiguous expansion of macro %0">, InGroup<AmbiguousMacro>; +def note_pp_ambiguous_macro_chosen : Note< + "expanding this definition of %0">; +def note_pp_ambiguous_macro_other : Note< + "other definition of %0">; def pp_invalid_string_literal : Warning< "invalid string literal, ignoring final '\\'">; @@ -484,15 +491,21 @@ def err_mmap_missing_module_unqualified : Error< def err_mmap_missing_module_qualified : Error< "no module named '%0' in '%1'">; def err_mmap_top_level_inferred_submodule : Error< - "only submodules may be inferred with wildcard syntax">; + "only submodules and framework modules may be inferred with wildcard syntax">; def err_mmap_inferred_no_umbrella : Error< "inferred submodules require a module with an umbrella">; +def err_mmap_inferred_framework_submodule : Error< + "inferred submodule cannot be a framework submodule">; +def err_mmap_explicit_inferred_framework : Error< + "inferred framework modules cannot be 'explicit'">; +def err_mmap_missing_exclude_name : Error< + "expected excluded module name">; def err_mmap_inferred_redef : Error< "redefinition of inferred submodule">; def err_mmap_expected_lbrace_wildcard : Error< "expected '{' to start inferred submodule">; -def err_mmap_expected_wildcard_member : Error< - "expected module export wildcard">; +def err_mmap_expected_inferred_member : Error< + "expected %select{module exclusion with 'exclude'|'export *'}0">; def err_mmap_expected_export_wildcard : Error< "only '*' can be exported from an inferred submodule">; def err_mmap_explicit_top_level : Error< @@ -509,5 +522,7 @@ def warn_auto_module_import : Warning< "import of module '%1'">, InGroup<AutoImport>, DefaultIgnore; def warn_uncovered_module_header : Warning< "umbrella header does not include header '%0'">, InGroup<IncompleteUmbrella>; - +def err_expected_id_building_module : Error< + "expected a module name in '__building_module' expression">; + } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.def b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.def new file mode 100644 index 0000000..476ac1e --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.def @@ -0,0 +1,93 @@ +//===--- DiagOptions.def - Diagnostic 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 diagnostic options. Users of this file +// must define the DIAGOPT macro to make use of this information. +// Optionally, the user may also define ENUM_DIAGOPT (for options +// that have enumeration type and VALUE_DIAGOPT (for options that +// describe a value rather than a flag). The SEMANTIC_* variants of these macros +// indicate options that affect the processing of the program, rather than +// simply the output. +// +//===----------------------------------------------------------------------===// +#ifndef DIAGOPT +# error Define the DIAGOPT macro to handle language options +#endif + +#ifndef VALUE_DIAGOPT +# define VALUE_DIAGOPT(Name, Bits, Default) \ +DIAGOPT(Name, Bits, Default) +#endif + +#ifndef ENUM_DIAGOPT +# define ENUM_DIAGOPT(Name, Type, Bits, Default) \ +DIAGOPT(Name, Bits, Default) +#endif + +#ifndef SEMANTIC_DIAGOPT +# define SEMANTIC_DIAGOPT(Name, Bits, Default) DIAGOPT(Name, Bits, Default) +#endif + +#ifndef SEMANTIC_VALUE_DIAGOPT +# define SEMANTIC_VALUE_DIAGOPT(Name, Bits, Default) \ + VALUE_DIAGOPT(Name, Bits, Default) +#endif + +#ifndef SEMANTIC_ENUM_DIAGOPT +# define SEMANTIC_ENUM_DIAGOPT(Name, Type, Bits, Default) \ + ENUM_DIAGOPT(Name, Type, Bits, Default) +#endif + +SEMANTIC_DIAGOPT(IgnoreWarnings, 1, 0) /// -w +DIAGOPT(NoRewriteMacros, 1, 0) /// -Wno-rewrite-macros +DIAGOPT(Pedantic, 1, 0) /// -pedantic +DIAGOPT(PedanticErrors, 1, 0) /// -pedantic-errors +DIAGOPT(ShowColumn, 1, 1) /// Show column number on diagnostics. +DIAGOPT(ShowLocation, 1, 1) /// Show source location information. +DIAGOPT(ShowCarets, 1, 1) /// Show carets in diagnostics. +DIAGOPT(ShowFixits, 1, 1) /// Show fixit information. +DIAGOPT(ShowSourceRanges, 1, 0) /// Show source ranges in numeric form. +DIAGOPT(ShowParseableFixits, 1, 0) /// Show machine parseable fix-its. +DIAGOPT(ShowOptionNames, 1, 0) /// Show the option name for mappable + /// diagnostics. +DIAGOPT(ShowNoteIncludeStack, 1, 0) /// Show include stacks for notes. +VALUE_DIAGOPT(ShowCategories, 2, 0) /// Show categories: 0 -> none, 1 -> Number, + /// 2 -> Full Name. + +ENUM_DIAGOPT(Format, TextDiagnosticFormat, 2, Clang) /// Format for diagnostics: + +DIAGOPT(ShowColors, 1, 0) /// Show diagnostics with ANSI color sequences. +ENUM_DIAGOPT(ShowOverloads, OverloadsShown, 1, + Ovl_All) /// Overload candidates to show. +DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected + /// diagnostics, indicated by markers in the + /// input source file. + +DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing +DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing + +VALUE_DIAGOPT(ErrorLimit, 32, 0) /// Limit # errors emitted. +/// Limit depth of macro expansion backtrace. +VALUE_DIAGOPT(MacroBacktraceLimit, 32, DefaultMacroBacktraceLimit) +/// Limit depth of instantiation backtrace. +VALUE_DIAGOPT(TemplateBacktraceLimit, 32, DefaultTemplateBacktraceLimit) +/// Limit depth of constexpr backtrace. +VALUE_DIAGOPT(ConstexprBacktraceLimit, 32, DefaultConstexprBacktraceLimit) + +VALUE_DIAGOPT(TabStop, 32, DefaultTabStop) /// The distance between tab stops. +/// Column limit for formatting message diagnostics, or 0 if unused. +VALUE_DIAGOPT(MessageLength, 32, 0) + +#undef DIAGOPT +#undef ENUM_DIAGOPT +#undef VALUE_DIAGOPT +#undef SEMANTIC_DIAGOPT +#undef SEMANTIC_ENUM_DIAGOPT +#undef SEMANTIC_VALUE_DIAGOPT + diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.h b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.h new file mode 100644 index 0000000..b75cb0c --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.h @@ -0,0 +1,85 @@ +//===--- DiagnosticOptions.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H +#define LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H + +#include "llvm/ADT/IntrusiveRefCntPtr.h" + +#include <string> +#include <vector> + +namespace clang { + +/// \brief Specifies which overload candidates to display when overload +/// resolution fails. +enum OverloadsShown { + Ovl_All, ///< Show all overloads. + Ovl_Best ///< Show just the "best" overload candidates. +}; + +/// DiagnosticOptions - Options for controlling the compiler diagnostics +/// engine. +class DiagnosticOptions : public llvm::RefCountedBase<DiagnosticOptions>{ +public: + enum TextDiagnosticFormat { Clang, Msvc, Vi }; + + // Default values. + enum { DefaultTabStop = 8, MaxTabStop = 100, + DefaultMacroBacktraceLimit = 6, + DefaultTemplateBacktraceLimit = 10, + DefaultConstexprBacktraceLimit = 10 }; + + // Define simple diagnostic options (with no accessors). +#define DIAGOPT(Name, Bits, Default) unsigned Name : Bits; +#define ENUM_DIAGOPT(Name, Type, Bits, Default) +#include "clang/Basic/DiagnosticOptions.def" + +protected: + // Define diagnostic options of enumeration type. These are private, and will + // have accessors (below). +#define DIAGOPT(Name, Bits, Default) +#define ENUM_DIAGOPT(Name, Type, Bits, Default) unsigned Name : Bits; +#include "clang/Basic/DiagnosticOptions.def" + +public: + /// If non-empty, a file to log extended build information to, for development + /// testing and analysis. + std::string DumpBuildInformation; + + /// The file to log diagnostic output to. + std::string DiagnosticLogFile; + + /// The file to serialize diagnostics to (non-appending). + std::string DiagnosticSerializationFile; + + /// The list of -W... options used to alter the diagnostic mappings, with the + /// prefixes removed. + std::vector<std::string> Warnings; + +public: + // Define accessors/mutators for diagnostic options of enumeration type. +#define DIAGOPT(Name, Bits, Default) +#define ENUM_DIAGOPT(Name, Type, Bits, Default) \ + Type get##Name() const { return static_cast<Type>(Name); } \ + void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } +#include "clang/Basic/DiagnosticOptions.def" + + DiagnosticOptions() { +#define DIAGOPT(Name, Bits, Default) Name = Default; +#define ENUM_DIAGOPT(Name, Type, Bits, Default) set##Name(Default); +#include "clang/Basic/DiagnosticOptions.def" + } +}; + +typedef DiagnosticOptions::TextDiagnosticFormat TextDiagnosticFormat; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td index b1c16fa..21eeccb 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -18,10 +18,13 @@ def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">, def warn_file_asm_volatile : Warning< "meaningless 'volatile' on asm outside function">, CatInlineAsm; +def warn_unsupported_msasm : Warning< + "MS-style inline assembly is not supported">, InGroup<Microsoft>; + let CategoryName = "Parse Issue" in { def ext_empty_translation_unit : Extension< - "ISO C requires a translation unit to contain at least one declaration.">, + "ISO C requires a translation unit to contain at least one declaration">, InGroup<DiagGroup<"empty-translation-unit">>; def warn_cxx98_compat_top_level_semi : Warning< "extra ';' outside of a function is incompatible with C++98">, @@ -40,11 +43,14 @@ def warn_extra_semi_after_mem_fn_def : Warning< "extra ';' after member function definition">, InGroup<ExtraSemi>, DefaultIgnore; -def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">; +def ext_duplicate_declspec : ExtWarn<"duplicate '%0' declaration specifier">, + InGroup<DuplicateDeclSpecifier>; +def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">, + InGroup<DuplicateDeclSpecifier>; def ext_plain_complex : ExtWarn< "plain '_Complex' requires a type specifier; assuming '_Complex double'">; def ext_integer_complex : Extension< - "complex integer types are an extension">; + "complex integer types are a GNU extension">, InGroup<GNU>; def ext_thread_before : Extension<"'__thread' before '%0'">; def ext_empty_struct_union : Extension< @@ -80,8 +86,11 @@ def err_enumerator_list_missing_comma : Error< "missing ',' between enumerators">; def err_enumerator_unnamed_no_def : Error< "unnamed enumeration must be a definition">; -def ext_ms_enum_fixed_underlying_type : Extension< - "enumeration types with a fixed underlying type are a Microsoft extension">, +def ext_cxx11_enum_fixed_underlying_type : Extension< + "enumeration types with a fixed underlying type are a C++11 extension">, + InGroup<CXX11>; +def ext_c_enum_fixed_underlying_type : Extension< + "enumeration types with a fixed underlying type are a Microsoft extension">, InGroup<Microsoft>; def warn_cxx98_compat_enum_fixed_underlying_type : Warning< "enumeration types with a fixed underlying type are incompatible with C++98">, @@ -207,6 +216,17 @@ def err_expected_semi_after_static_assert : Error< "expected ';' after static_assert">; def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">; def err_expected_colon_after : Error<"expected ':' after %0">; +def warn_missing_selector_name : Warning< + "%0 used as the name of the previous parameter rather than as part " + "of the selector">, + InGroup<DiagGroup<"missing-selector-name">>; +def note_missing_selector_name : Note< + "introduce a parameter name to make %0 part of the selector">; +def note_force_empty_selector_name : Note< + "or insert whitespace before ':' to use %0 as parameter name " + "and have an empty entry in the selector">; +def note_missing_argument_name : Note< + "did you mean to use %0 as the selector name instead of %1">; def err_label_end_of_compound_statement : Error< "label at end of compound statement: expected statement">; def err_address_of_label_outside_fn : Error< @@ -331,6 +351,8 @@ def ext_c11_static_assert : Extension< def warn_cxx98_compat_static_assert : Warning< "static_assert declarations are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; +def err_paren_after_colon_colon : Error< + "unexpected parenthesis after '::'">; /// Objective-C parser diagnostics def err_expected_minus_or_plus : Error< @@ -423,7 +445,8 @@ def err_expected_member_or_base_name : Error< def err_expected_lbrace_after_base_specifiers : Error< "expected '{' after base class list">; def ext_ellipsis_exception_spec : Extension< - "exception specification of '...' is a Microsoft extension">; + "exception specification of '...' is a Microsoft extension">, + InGroup<Microsoft>; def err_dynamic_and_noexcept_specification : Error< "cannot have both throw() and noexcept() clause on the same function">; def warn_cxx98_compat_noexcept_decl : Warning< @@ -455,9 +478,6 @@ def err_literal_operator_string_prefix : Error< "string literal after 'operator' cannot have an encoding prefix">; def err_literal_operator_string_not_empty : Error< "string literal after 'operator' must be '\"\"'">; -def err_literal_operator_missing_space : Error< - "C++11 requires a space between the \"\" and the user-defined suffix in a " - "literal operator">; def warn_cxx98_compat_literal_operator : Warning< "literal operators are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; @@ -570,7 +590,7 @@ def err_expected_type_name_after_typename : Error< "expected an identifier or template-id after '::'">; def err_explicit_spec_non_template : Error< "explicit %select{specialization|instantiation}0 of non-template " - "%select{class|struct|union}1 %2">; + "%select{class|struct|union|interface}1 %2">; def err_default_template_template_parameter_not_template : Error< "default template argument for a template template parameter must be a class " @@ -627,6 +647,11 @@ def ext_override_control_keyword : ExtWarn< def warn_cxx98_compat_override_control_keyword : Warning< "'%0' keyword is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; +def err_override_control_interface : Error< + "'%0' keyword not permitted with interface types">; + +def err_access_specifier_interface : Error< + "interface types cannot specify '%select{private|protected}0' access">; def err_duplicate_virt_specifier : Error< "class member already marked '%0'">; @@ -710,6 +735,11 @@ def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">; def warn_pragma_unused_expected_punc : Warning< "expected ')' or ',' in '#pragma unused'">; +// - #pragma fp_contract +def err_pragma_fp_contract_scope : Error< + "'#pragma fp_contract' should only appear at file scope or at the start of a " + "compound expression">; + // OpenCL Section 6.8.g def err_not_opencl_storage_class_specifier : Error< diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index 96b3140..0d64bf3 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -20,13 +20,6 @@ def warn_variables_not_in_loop_body : Warning< "used in loop condition not modified in loop body">, InGroup<DiagGroup<"loop-analysis">>, DefaultIgnore; -def warn_identical_enum_values : Warning< - "all elements of %0 are initialized with literals to value %1">, - InGroup<DiagGroup<"unique-enum">>; -def note_identical_enum_values : Note< - "initialize the last element with the previous element to silence " - "this warning">; - // Constant expressions def err_expr_not_ice : Error< "expression is not an %select{integer|integral}0 constant expression">; @@ -102,7 +95,7 @@ def err_variably_modified_new_type : Error< // C99 Designated Initializers def ext_designated_init : Extension< - "designated initializers are a C99 feature">; + "designated initializers are a C99 feature">, InGroup<C99>; def err_array_designator_negative : Error< "array designator value '%0' is negative">; def err_array_designator_empty_range : Error< @@ -410,12 +403,10 @@ def err_statically_allocated_object : Error< "interface type cannot be statically allocated">; 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">; + "; 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'">; def warn_pragma_options_align_reset_failed : Warning< "#pragma options align=reset failed: %0">; def err_pragma_options_align_mac68k_target_unsupported : Error< @@ -521,7 +512,8 @@ def warn_conflicting_overriding_ret_types : Warning< def warn_conflicting_ret_types : Warning< "conflicting return type in " - "implementation of %0%diff{: $ vs $|}1,2">; + "implementation of %0%diff{: $ vs $|}1,2">, + InGroup<MismatchedReturnTypes>; def warn_conflicting_overriding_ret_type_modifiers : Warning< "conflicting distributed object modifiers on return type " @@ -550,7 +542,9 @@ def warn_conflicting_overriding_param_types : Warning< def warn_conflicting_param_types : Warning< "conflicting parameter types in " - "implementation of %0%diff{: $ vs $|}1,2">; + "implementation of %0%diff{: $ vs $|}1,2">, + InGroup<MismatchedParameterTypes>; + def warn_conflicting_param_modifiers : Warning< "conflicting distributed object modifiers on parameter type " "in implementation of %0">, @@ -595,6 +589,8 @@ def warn_accessor_property_type_mismatch : Warning< "type of property %0 does not match type of accessor %1">; def not_conv_function_declared_at : Note<"type conversion function declared here">; def note_method_declared_at : Note<"method %0 declared here">; +def note_property_attribute : Note<"property %0 is declared " + "%select{deprecated|unavailable}1 here">; def err_setter_type_void : Error<"type of setter must be void">; def err_duplicate_method_decl : Error<"duplicate declaration of method %0">; def warn_duplicate_method_decl : @@ -700,7 +696,7 @@ def error_bad_property_context : Error< "property implementation must be in a class or category implementation">; def error_missing_property_ivar_decl : Error< "synthesized property %0 must either be named the same as a compatible" - " ivar or must explicitly name an ivar">; + " instance variable or must explicitly name an instance variable">; def error_synthesize_weak_non_arc_or_gc : Error< "@synthesize of 'weak' property is only allowed in ARC or GC mode">; def err_arc_perform_selector_retains : Error< @@ -712,38 +708,55 @@ def err_gc_weak_property_strong_type : Error< "weak attribute declared on a __strong type property in GC mode">; def warn_receiver_is_weak : Warning < "weak %select{receiver|property|implicit property}0 may be " - "unpredictably null in ARC mode">, + "unpredictably set to nil">, InGroup<DiagGroup<"receiver-is-weak">>, DefaultIgnore; +def note_arc_assign_to_strong : Note< + "assign the value to a strong variable to keep the object alive during use">; +def warn_arc_repeated_use_of_weak : Warning < + "weak %select{variable|property|implicit property|instance variable}0 %1 is " + "accessed multiple times in this %select{function|method|block|lambda}2 " + "but may be unpredictably set to nil; assign to a strong variable to keep " + "the object alive">, + InGroup<ARCRepeatedUseOfWeak>, DefaultIgnore; +def warn_implicitly_retains_self : Warning < + "block implicitly retains 'self'; explicitly mention 'self' to indicate " + "this is intended behavior">, + InGroup<DiagGroup<"implicit-retain-self">>, DefaultIgnore; +def warn_arc_possible_repeated_use_of_weak : Warning < + "weak %select{variable|property|implicit property|instance variable}0 %1 may " + "be accessed multiple times in this %select{function|method|block|lambda}2 " + "and may be unpredictably set to nil; assign to a strong variable to keep " + "the object alive">, + InGroup<ARCRepeatedUseOfWeakMaybe>, DefaultIgnore; +def note_arc_weak_also_accessed_here : Note< + "also accessed here">; def err_incomplete_synthesized_property : Error< "cannot synthesize property %0 with incomplete type %1">; def error_property_ivar_type : Error< - "type of property %0 (%1) does not match type of ivar %2 (%3)">; + "type of property %0 (%1) does not match type of instance variable %2 (%3)">; def error_property_accessor_type : Error< "type of property %0 (%1) does not match type of accessor %2 (%3)">; def error_ivar_in_superclass_use : Error< - "property %0 attempting to use ivar %1 declared in super class %2">; + "property %0 attempting to use instance variable %1 declared in super class %2">; def error_weak_property : Error< - "existing ivar %1 for __weak property %0 must be __weak">; + "existing instance variable %1 for __weak property %0 must be __weak">; def error_strong_property : Error< - "existing ivar %1 for strong property %0 may not be __weak">; + "existing instance variable %1 for strong property %0 may not be __weak">; def error_dynamic_property_ivar_decl : Error< - "dynamic property can not have ivar specification">; + "dynamic property can not have instance variable specification">; def error_duplicate_ivar_use : Error< - "synthesized properties %0 and %1 both claim ivar %2">; + "synthesized properties %0 and %1 both claim instance variable %2">; def error_property_implemented : Error<"property %0 is already implemented">; def warn_objc_property_attr_mutually_exclusive : Warning< "property attributes '%0' and '%1' are mutually exclusive">, InGroup<ReadOnlySetterAttrs>, DefaultIgnore; -def warn_objc_missing_super_dealloc : Warning< - "method possibly missing a [super dealloc] call">, +def warn_objc_missing_super_call : Warning< + "method possibly missing a [super %0] call">, InGroup<ObjCMissingSuperCalls>; def error_dealloc_bad_result_type : Error< "dealloc return type must be correctly specified as 'void' under ARC, " "instead of %0">; -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< @@ -768,7 +781,7 @@ def err_static_assert_expression_is_not_constant : Error< def err_static_assert_failed : Error<"static_assert failed %0">; def warn_inline_namespace_reopened_noninline : Warning< - "inline namespace cannot be re-opened as a non-inline namespace">; + "inline namespace cannot be reopened as a non-inline namespace">; def err_inline_namespace_mismatch : Error< "%select{|non-}0inline namespace " "cannot be reopened as %select{non-|}0inline">; @@ -792,10 +805,11 @@ def warn_cxx98_compat_friend_is_member : Warning< "with C++98">, InGroup<CXX98Compat>, DefaultIgnore; def ext_unelaborated_friend_type : ExtWarn< "unelaborated friend declaration is a C++11 extension; specify " - "'%select{struct|union|class|enum}0' to befriend %1">, InGroup<CXX11>; + "'%select{struct|interface|union|class|enum}0' to befriend %1">, + InGroup<CXX11>; def warn_cxx98_compat_unelaborated_friend_type : Warning< - "befriending %1 without '%select{struct|union|class|enum}0' keyword is " - "incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; + "befriending %1 without '%select{struct|interface|union|class|enum}0' " + "keyword is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; 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< @@ -806,16 +820,26 @@ def err_tagless_friend_type_template : Error< 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">; + "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_friend_not_first_in_declaration : Error< + "'friend' must appear first in a non-function declaration">; +def err_invalid_member_in_interface : Error< + "%select{data member |non-public member function |static member function |" + "user-declared constructor|user-declared destructor|operator |" + "nested class }0%1 is not permitted within an interface type">; +def err_invalid_base_in_interface : Error< + "interface type cannot inherit from " + "%select{'struct|non-public 'interface|'class}0 %1'">; + def err_abstract_type_in_decl : Error< - "%select{return|parameter|variable|field|ivar}0 type %1 is an abstract class">; + "%select{return|parameter|variable|field|instance variable}0 type %1 is an abstract class">; def err_allocation_of_abstract_type : Error< "allocating an object of abstract class type %0">; def err_throw_abstract_type : Error< @@ -841,6 +865,12 @@ def note_pure_virtual_function : Note< def err_deleted_decl_not_first : Error< "deleted definition must be first declaration">; +def err_deleted_override : Error< + "deleted function %0 cannot override a non-deleted function">; + +def err_non_deleted_override : Error< + "non-deleted function %0 cannot override a deleted function">; + def warn_weak_vtable : Warning< "%0 has no out-of-line virtual method definitions; its vtable will be " "emitted in every translation unit">, @@ -1030,7 +1060,7 @@ def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning< "not available in the %select{constructor|destructor}1 of %2">; def note_field_decl : Note<"member is declared here">; -def note_ivar_decl : Note<"ivar is declared here">; +def note_ivar_decl : Note<"instance variable is declared here">; def note_bitfield_decl : Note<"bit-field is declared here">; def note_previous_decl : Note<"%0 declared here">; def note_member_synthesized_at : Note< @@ -1113,8 +1143,8 @@ def err_constructor_redeclared : Error<"constructor cannot be redeclared">; def err_constructor_byvalue_arg : Error< "copy constructor must pass its first argument by reference">; def warn_no_constructor_for_refconst : Warning< - "%select{struct|union|class|enum}0 %1 does not declare any constructor to " - "initialize its non-modifiable members">; + "%select{struct|interface|union|class|enum}0 %1 does not declare any " + "constructor to initialize its non-modifiable members">; def note_refconst_member_not_initialized : Note< "%select{const|reference}0 member %1 will never be initialized">; def ext_ms_explicit_constructor_call : ExtWarn< @@ -1214,11 +1244,18 @@ def err_init_reference_member_uninitialized : Error< "reference member of type %0 uninitialized">; def note_uninit_reference_member : Note< "uninitialized reference member is here">; -def warn_field_is_uninit : Warning<"field is uninitialized when used here">, +def warn_field_is_uninit : Warning<"field %0 is uninitialized when used here">, + InGroup<Uninitialized>; +def warn_reference_field_is_uninit : Warning< + "reference %0 is not yet bound to a value when used here">, InGroup<Uninitialized>; def warn_uninit_self_reference_in_init : Warning< "variable %0 is uninitialized when used within its own initialization">, InGroup<Uninitialized>; +def warn_uninit_self_reference_in_reference_init : Warning< + "reference %0 is not yet bound to a value when used within its own" + " initialization">, + InGroup<Uninitialized>; def warn_uninit_var : Warning< "variable %0 is uninitialized when %select{used here|captured by block}1">, InGroup<Uninitialized>, DefaultIgnore; @@ -1300,9 +1337,10 @@ def err_new_array_of_auto : Error< "cannot allocate array of 'auto'">; def err_auto_not_allowed : Error< "'auto' not allowed %select{in function prototype|in non-static struct member" - "|in non-static union member|in non-static class member|in exception declaration" - "|in template parameter|in block literal|in template argument" - "|in typedef|in type alias|in function return type|here}0">; + "|in non-static union member|in non-static class member|in interface member" + "|in exception declaration|in template parameter|in block literal" + "|in template argument|in typedef|in type alias|in function return type" + "|here}0">; def err_auto_var_requires_init : Error< "declaration of variable %0 with type %1 requires an initializer">; def err_auto_new_requires_ctor_arg : Error< @@ -1346,6 +1384,8 @@ def err_function_marked_override_not_overriding : Error< "%0 marked 'override' but does not override any member functions">; def err_class_marked_final_used_as_base : Error< "base %0 is marked 'final'">; +def warn_abstract_final_class : Warning< + "abstract class is marked 'final'">, InGroup<AbstractFinalClass>; // C++11 attributes def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">; @@ -1408,7 +1448,17 @@ def err_for_range_member_begin_end_mismatch : Error< "range type %0 has '%select{begin|end}1' member but no '%select{end|begin}1' member">; def err_for_range_begin_end_types_differ : Error< "'begin' and 'end' must return the same type (got %0 and %1)">; -def note_for_range_type : Note<"range has type %0">; +def note_in_for_range: Note< + "when looking up '%select{begin|end}0' function for range expression " + "of type %1">; +def err_for_range_invalid: Error< + "invalid range expression of type %0; no viable '%select{begin|end}1' " + "function available">; +def err_for_range_dereference : Error< + "invalid range expression of type %0; did you mean to dereference it " + "with '*'?">; +def note_for_range_invalid_iterator : Note < + "in implicit call to 'operator%select{!=|*|++}0' for iterator of type %1">; def note_for_range_begin_end : Note< "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">; @@ -1420,7 +1470,7 @@ 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">; + "%select{class|struct|interface|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">; @@ -1438,11 +1488,12 @@ def err_constexpr_redecl_mismatch : Error< def err_constexpr_virtual : Error<"virtual function cannot be constexpr">; def err_constexpr_virtual_base : Error< "constexpr %select{member function|constructor}0 not allowed in " - "%select{class|struct}1 with virtual base %plural{1:class|:classes}2">; + "%select{struct|interface|class}1 with virtual base " + "%plural{1:class|:classes}2">; def note_non_literal_incomplete : Note< "incomplete type %0 is not a literal type">; -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_non_literal_virtual_base : Note<"%select{struct|interface|class}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">; @@ -1490,10 +1541,10 @@ def note_non_literal_user_provided_dtor : Note< def note_non_literal_nontrivial_dtor : Note< "%0 is not literal because it has a non-trivial destructor">; def warn_private_extern : Warning< - "Use of __private_extern__ on tentative definition has unexpected" - " behaviour - use __attribute__((visibility(\"hidden\"))) on extern" - " declaration or definition instead">, - InGroup<PrivateExtern>, DefaultIgnore; + "use of __private_extern__ on a declaration may not produce external symbol " + "private to the linkage unit and is deprecated">, InGroup<PrivateExtern>; +def note_private_extern : Note< + "use __attribute__((visibility(\"hidden\"))) attribute instead">; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< @@ -1681,7 +1732,9 @@ def warn_attribute_invalid_on_stmt : Warning< "attribute %0 cannot be specified on a statement">, InGroup<IgnoredAttributes>; def warn_declspec_attribute_ignored : Warning< - "attribute %0 is ignored, place it after \"%select{class|struct|union|enum}1\" to apply attribute to type declaration">, InGroup<IgnoredAttributes>; + "attribute %0 is ignored, place it after " + "\"%select{class|struct|union|interface|enum}1\" to apply attribute to " + "type declaration">, InGroup<IgnoredAttributes>; def warn_attribute_precede_definition : Warning< "attribute declaration must precede definition">, InGroup<IgnoredAttributes>; @@ -1699,7 +1752,8 @@ def warn_nsobject_attribute : Warning< "__attribute ((NSObject)) may be put on a typedef only, " "attribute is ignored">, InGroup<NSobjectAttribute>; def warn_attribute_weak_on_local : Warning< - "__weak attribute cannot be specified on an automatic variable">, + "__weak attribute cannot be specified on an automatic variable when ARC " + "is not enabled">, InGroup<IgnoredAttributes>; def warn_weak_identifier_undeclared : Warning< "weak identifier %0 never declared">; @@ -1753,6 +1807,8 @@ def err_attribute_vecreturn_only_pod_record : Error< def err_cconv_change : Error< "function declared '%0' here was previously declared " "%select{'%2'|without calling convention}1">; +def warn_cconv_ignored : Warning< + "calling convention %0 ignored for this target">, InGroup<IgnoredAttributes>; def err_cconv_knr : Error< "function with no prototype cannot use %0 calling convention">; def err_cconv_varargs : Error< @@ -1840,14 +1896,6 @@ def warn_lock_exclusive_and_shared : Warning< InGroup<ThreadSafetyAnalysis>, DefaultIgnore; def note_lock_exclusive_and_shared : Note< "the other lock of mutex '%0' is here">; -def warn_variable_requires_lock : Warning< - "%select{reading|writing}2 variable '%0' requires locking " - "%select{'%1'|'%1' exclusively}2">, - InGroup<ThreadSafetyAnalysis>, DefaultIgnore; -def warn_var_deref_requires_lock : Warning< - "%select{reading|writing}2 the value pointed to by '%0' requires locking " - "%select{'%1'|'%1' exclusively}2">, - InGroup<ThreadSafetyAnalysis>, DefaultIgnore; def warn_variable_requires_any_lock : Warning< "%select{reading|writing}1 variable '%0' requires locking " "%select{any mutex|any mutex exclusively}1">, @@ -1856,9 +1904,6 @@ 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<ThreadSafetyAnalysis>, DefaultIgnore; -def warn_fun_requires_lock : Warning< - "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">, - InGroup<ThreadSafetyAnalysis>, DefaultIgnore; def warn_fun_excludes_mutex : Warning< "cannot call function '%0' while mutex '%1' is locked">, InGroup<ThreadSafetyAnalysis>, DefaultIgnore; @@ -1866,6 +1911,32 @@ def warn_cannot_resolve_lock : Warning< "cannot resolve lock expression">, InGroup<ThreadSafetyAnalysis>, DefaultIgnore; +// Imprecise thread safety warnings +def warn_variable_requires_lock : Warning< + "%select{reading|writing}2 variable '%0' requires locking " + "%select{'%1'|'%1' exclusively}2">, + InGroup<ThreadSafetyAnalysis>, DefaultIgnore; +def warn_var_deref_requires_lock : Warning< + "%select{reading|writing}2 the value pointed to by '%0' requires locking " + "%select{'%1'|'%1' exclusively}2">, + InGroup<ThreadSafetyAnalysis>, DefaultIgnore; +def warn_fun_requires_lock : Warning< + "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">, + InGroup<ThreadSafetyAnalysis>, DefaultIgnore; + +// Precise thread safety warnings +def warn_variable_requires_lock_precise : Warning< + "%select{reading|writing}2 variable '%0' requires locking " + "%select{'%1'|'%1' exclusively}2">, + InGroup<ThreadSafetyPrecise>, DefaultIgnore; +def warn_var_deref_requires_lock_precise : Warning< + "%select{reading|writing}2 the value pointed to by '%0' requires locking " + "%select{'%1'|'%1' exclusively}2">, + InGroup<ThreadSafetyPrecise>, DefaultIgnore; +def warn_fun_requires_lock_precise : Warning< + "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">, + InGroup<ThreadSafetyPrecise>, DefaultIgnore; +def note_found_mutex_near_match : Note<"found near match '%0'">; def warn_impcast_vector_scalar : Warning< "implicit conversion turns vector to scalar: %0 to %1">, @@ -1890,7 +1961,7 @@ def warn_impcast_integer_precision : Warning< InGroup<DiagGroup<"conversion">>, DefaultIgnore; def warn_impcast_integer_64_32 : Warning< "implicit conversion loses integer precision: %0 to %1">, - InGroup<DiagGroup<"shorten-64-to-32">>, DefaultIgnore; + InGroup<Shorten64To32>, DefaultIgnore; def warn_impcast_integer_precision_constant : Warning< "implicit conversion from %2 to %3 changes value from %0 to %1">, InGroup<ConstantConversion>; @@ -1905,7 +1976,7 @@ def warn_impcast_string_literal_to_bool : Warning< InGroup<StringConversion>, DefaultIgnore; def warn_impcast_different_enum_types : Warning< "implicit conversion from enumeration type %0 to different enumeration type " - "%1">, InGroup<DiagGroup<"conversion">>; + "%1">, InGroup<EnumConversion>; def warn_impcast_bool_to_null_pointer : Warning< "initialization of pointer of type %0 to null from a constant boolean " "expression">, InGroup<BoolConversion>; @@ -1915,6 +1986,9 @@ def warn_non_literal_null_pointer : Warning< def warn_impcast_null_pointer_to_integer : Warning< "implicit conversion of NULL constant to %0">, InGroup<NullConversion>; +def warn_impcast_floating_point_to_bool : Warning< + "implicit conversion turns floating-point number into bool: %0 to %1">, + InGroup<ImplicitConversionFloatingPointToBool>; def warn_impcast_function_to_bool : Warning< "address of function %q0 will always evaluate to 'true'">, InGroup<BoolConversion>; @@ -1927,6 +2001,10 @@ def warn_cast_align : Warning< "cast from %0 to %1 increases required alignment from %2 to %3">, InGroup<CastAlign>, DefaultIgnore; +def warn_int_to_pointer_cast : Warning< + "cast to %1 from smaller integer type %0">, + InGroup<IntToPointerCast>; + def warn_attribute_ignored_for_field_of_type : Warning< "%0 attribute ignored for field of type %1">, InGroup<IgnoredAttributes>; @@ -2008,7 +2086,7 @@ def warn_attribute_ibaction: Warning< def err_iboutletcollection_type : Error< "invalid type %0 as argument of iboutletcollection attribute">; def warn_iboutlet_object_type : Warning< - "%select{ivar|property}2 with %0 attribute must " + "%select{instance variable|property}2 with %0 attribute must " "be an object type (invalid %1)">, InGroup<DiagGroup<"invalid-iboutlet">>; def err_attribute_overloadable_not_function : Error< @@ -2028,6 +2106,12 @@ def warn_ns_attribute_wrong_parameter_type : Warning< "%0 attribute only applies to %select{Objective-C object|pointer}1 " "parameters">, InGroup<IgnoredAttributes>; +def warn_objc_requires_super_protocol : Warning< + "%0 attribute cannot be applied to %select{methods in protocols|dealloc}1">, + InGroup<DiagGroup<"requires-super-attribute">>; +def note_protocol_decl : Note< + "protocol is declared here">; + def err_ns_bridged_not_interface : Error< "parameter of 'ns_bridged' attribute does not name an Objective-C class">; @@ -3147,7 +3231,7 @@ def err_non_thread_thread : Error< def err_thread_non_thread : Error< "thread-local declaration of %0 follows non-thread-local declaration">; def err_redefinition_different_type : Error< - "redefinition of %0 with a different type">; + "redefinition of %0 with a different type%diff{: $ vs $|}1,2">; def err_redefinition_different_kind : Error< "redefinition of %0 as different kind of symbol">; def warn_forward_class_redefinition : Warning< @@ -3162,8 +3246,8 @@ def err_tag_reference_conflict : Error< "implicit declaration introduced by elaborated type conflicts with " "%select{a declaration|a typedef|a type alias|a template}0 of the same name">; def err_dependent_tag_decl : Error< - "%select{declaration|definition}0 of %select{struct|union|class|enum}1 " - "in a dependent scope">; + "%select{declaration|definition}0 of " + "%select{struct|interface|union|class|enum}1 in a dependent scope">; def err_tag_definition_of_typedef : Error< "definition of type %0 conflicts with %select{typedef|type alias}1 of the same name">; def err_conflicting_types : Error<"conflicting types for %0">; @@ -3171,15 +3255,16 @@ def err_nested_redefinition : Error<"nested redefinition of %0">; def err_use_with_wrong_tag : Error< "use of %0 with tag type that does not match previous declaration">; def warn_struct_class_tag_mismatch : Warning< - "%select{struct|class}0%select{| template}1 %2 was previously declared " - "as a %select{class|struct}0%select{| template}1">, + "%select{struct|interface|class}0%select{| template}1 %2 was previously " + "declared as a %select{struct|interface|class}3%select{| template}1">, InGroup<MismatchedTags>, DefaultIgnore; def warn_struct_class_previous_tag_mismatch : Warning< - "%2 defined as a %select{struct|class}0%select{| template}1 here but " - "previously declared as a %select{class|struct}0%select{| template}1">, + "%2 defined as %select{a struct|an interface|a class}0%select{| template}1 " + "here but previously declared as " + "%select{a struct|an interface|a class}3%select{| template}1">, InGroup<MismatchedTags>, DefaultIgnore; def note_struct_class_suggestion : Note< - "did you mean %select{struct|class}0 here?">; + "did you mean %select{struct|interface|class}0 here?">; def ext_forward_ref_enum : Extension< "ISO C forbids forward references to 'enum' types">; def err_forward_ref_enum : Error< @@ -3192,9 +3277,9 @@ def ext_forward_ref_enum_def : Extension< def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">; def err_duplicate_member : Error<"duplicate member %0">; def err_misplaced_ivar : Error< - "ivars may not be placed in %select{categories|class extension}0">; + "instance variables may not be placed in %select{categories|class extension}0">; def warn_ivars_in_interface : Warning< - "declaration of ivars in the interface is deprecated">, + "declaration of instance variables in the interface is deprecated">, InGroup<DiagGroup<"objc-interface-ivars">>, DefaultIgnore; def ext_enum_value_not_int : Extension< "ISO C restricts enumerator values to range of 'int' (%0 is too " @@ -3223,11 +3308,13 @@ def warn_array_new_too_large : Warning<"array is too large (%0 elements)">, // -Wpadded, -Wpacked def warn_padded_struct_field : Warning< - "padding %select{struct|class}0 %1 with %2 %select{byte|bit}3%select{|s}4 " - "to align %5">, InGroup<Padded>, DefaultIgnore; + "padding %select{struct|interface|class}0 %1 with %2 " + "%select{byte|bit}3%select{|s}4 to align %5">, + InGroup<Padded>, DefaultIgnore; def warn_padded_struct_anon_field : Warning< - "padding %select{struct|class}0 %1 with %2 %select{byte|bit}3%select{|s}4 " - "to align anonymous bit-field">, InGroup<Padded>, DefaultIgnore; + "padding %select{struct|interface|class}0 %1 with %2 " + "%select{byte|bit}3%select{|s}4 to align anonymous bit-field">, + InGroup<Padded>, DefaultIgnore; def warn_padded_struct_size : Warning< "padding size of %0 with %1 %select{byte|bit}2%select{|s}3 " "to alignment boundary">, InGroup<Padded>, DefaultIgnore; @@ -3247,7 +3334,7 @@ def err_typecheck_invalid_restrict_not_pointer_noarg : Error< def err_typecheck_invalid_restrict_invalid_pointee : Error< "pointer to function type %0 may not be 'restrict' qualified">; def ext_typecheck_zero_array_size : Extension< - "zero size arrays are an extension">; + "zero size arrays are an extension">, InGroup<ZeroLengthArray>; def err_typecheck_zero_array_size : Error< "zero-length arrays are not permitted in C++">; def warn_typecheck_zero_static_array_size : Warning< @@ -3357,7 +3444,7 @@ def warn_anon_bitfield_width_exceeds_type_size : Warning< def warn_missing_braces : Warning< "suggest braces around initialization of subobject">, - InGroup<DiagGroup<"missing-braces">>, DefaultIgnore; + InGroup<MissingBraces>, DefaultIgnore; def err_missing_braces : Error< "cannot omit braces around initialization of subobject when using direct " "list-initialization">; @@ -3475,14 +3562,16 @@ def ext_flexible_array_in_array : Extension< 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>; + "flexible array member %0 in otherwise empty " + "%select{struct|interface|union|class|enum}1 is a Microsoft extension">, + InGroup<Microsoft>; def ext_flexible_array_union_ms : Extension< "flexible array member %0 in a union is a Microsoft extension">, InGroup<Microsoft>; def ext_flexible_array_empty_aggregate_gnu : Extension< - "flexible array member %0 in otherwise empty %select{struct|class}1 " - "is a GNU extension">, InGroup<GNU>; + "flexible array member %0 in otherwise empty " + "%select{struct|interface|union|class|enum}1 is a GNU extension">, + InGroup<GNU>; def ext_flexible_array_union_gnu : Extension< "flexible array member %0 in a union is a GNU extension">, InGroup<GNU>; @@ -3500,7 +3589,7 @@ def err_arc_weak_unavailable_assign : Error< "assignment of a weak-unavailable object to a __weak object">; def err_arc_weak_unavailable_property : Error< "synthesis of a weak-unavailable property is disallowed " - "because it requires synthesis of an ivar of the __weak object">; + "because it requires synthesis of an instance variable of the __weak object">; def err_arc_convesion_of_weak_unavailable : Error< "%select{implicit conversion|cast}0 of weak-unavailable object of type %1 to" " a __weak object of type %2">; @@ -3530,6 +3619,9 @@ def err_arc_illegal_selector : Error< "ARC forbids use of %0 in a @selector">; def err_arc_illegal_method_def : Error< "ARC forbids implementation of %0">; +def warn_arc_strong_pointer_objc_pointer : Warning< + "method parameter of type %0 with no explicit ownership">, + InGroup<DiagGroup<"explicit-ownership-type">>, DefaultIgnore; } // end "ARC Restrictions" category @@ -3552,11 +3644,6 @@ def err_typecheck_arc_assign_self_class_method : Error< def err_typecheck_arr_assign_enumeration : Error< "fast enumeration variables can't be modified in ARC by default; " "declare the variable __strong to allow this">; -def warn_arc_non_pod_class_with_object_member : Warning< - "%0 cannot be shared between ARC and non-ARC " - "code; add a copy constructor, a copy assignment operator, and a destructor " - "to make it ABI-compatible">, InGroup<AutomaticReferenceCountingABI>, - DefaultIgnore; def warn_arc_retained_assign : Warning< "assigning retained object to %select{weak|unsafe_unretained}0 " "%select{property|variable}1" @@ -3566,19 +3653,10 @@ def warn_arc_retained_property_assign : Warning< "assigning retained object to unsafe property" "; object will be released after assignment">, InGroup<ARCUnsafeRetainedAssign>; -def warn_arc_trivial_member_function_with_object_member : Warning< - "%0 cannot be shared between ARC and non-ARC " - "code; add a non-trivial %select{copy constructor|copy assignment operator|" - "destructor}1 to make it ABI-compatible">, - InGroup<AutomaticReferenceCountingABI>, DefaultIgnore; def err_arc_new_array_without_ownership : Error< "'new' cannot allocate an array of %0 with no explicit ownership">; -def warn_err_new_delete_object_array : Warning< - "%select{allocating|destroying}0 an array of %1; this array must not " - "%select{be deleted in|have been allocated from}0 non-ARC code">, - InGroup<AutomaticReferenceCountingABI>, DefaultIgnore; def err_arc_autoreleasing_var : Error< - "%select{__block variables|global variables|fields|ivars}0 cannot have " + "%select{__block variables|global variables|fields|instance variables}0 cannot have " "__autoreleasing ownership">; def err_arc_autoreleasing_capture : Error< "cannot capture __autoreleasing variable in a " @@ -3635,10 +3713,10 @@ def warn_arc_object_memaccess : Warning< let CategoryName = "ARC and @properties" in { def err_arc_strong_property_ownership : Error< - "existing ivar %1 for strong property %0 may not be " + "existing instance variable %1 for strong property %0 may not be " "%select{|__unsafe_unretained||__weak}2">; def err_arc_assign_property_ownership : Error< - "existing ivar %1 for property %0 with %select{unsafe_unretained| assign}2 " + "existing instance variable %1 for property %0 with %select{unsafe_unretained| assign}2 " "attribute must be __unsafe_unretained">; def err_arc_inconsistent_property_ownership : Error< "%select{|unsafe_unretained|strong|weak}1 property %0 may not also be " @@ -3769,16 +3847,14 @@ def warn_precedence_bitwise_rel : Warning< InGroup<Parentheses>; def note_precedence_bitwise_first : Note< "place parentheses around the %0 expression to evaluate it first">; -def note_precedence_bitwise_silence : Note< - "place parentheses around the %0 expression to silence this warning">; +def note_precedence_silence : Note< + "place parentheses around the '%0' expression to silence this warning">; def warn_precedence_conditional : Warning< "operator '?:' has lower precedence than '%0'; '%0' will be evaluated first">, InGroup<Parentheses>; def note_precedence_conditional_first : Note< "place parentheses around the '?:' expression to evaluate it first">; -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">, @@ -3790,13 +3866,13 @@ def note_logical_instead_of_bitwise_remove_constant : Note< def warn_bitwise_and_in_bitwise_or : Warning< "'&' within '|'">, InGroup<BitwiseOpParentheses>; -def note_bitwise_and_in_bitwise_or_silence : Note< - "place parentheses around the '&' expression to silence this warning">; def warn_logical_and_in_logical_or : Warning< "'&&' within '||'">, InGroup<LogicalOpParentheses>; -def note_logical_and_in_logical_or_silence : Note< - "place parentheses around the '&&' expression to silence this warning">; + +def warn_addition_in_bitshift : Warning< + "operator '%0' has lower precedence than '%1'; " + "'%1' will be evaluated first">, InGroup<ShiftOpParentheses>; def warn_self_assignment : Warning< "explicitly assigning a variable of type %0 to itself">, @@ -3899,6 +3975,8 @@ def ext_out_of_line_declaration : ExtWarn< "out-of-line declaration of a member must be a definition">, InGroup<OutOfLineDeclaration>, DefaultError; def warn_member_extra_qualification : Warning< + "extra qualification on member %0">, InGroup<Microsoft>; +def err_member_extra_qualification : Error< "extra qualification on member %0">; def err_member_qualification : Error< "non-friend class member %0 cannot have a qualified name">; @@ -4016,7 +4094,8 @@ def ext_typecheck_comparison_of_pointer_integer : ExtWarn< def err_typecheck_comparison_of_pointer_integer : Error< "comparison between pointer and integer (%0 and %1)">; def ext_typecheck_comparison_of_distinct_pointers : ExtWarn< - "comparison of distinct pointer types%diff{ ($ and $)|}0,1">; + "comparison of distinct pointer types%diff{ ($ and $)|}0,1">, + InGroup<CompareDistinctPointerType>; def ext_typecheck_cond_incompatible_operands : ExtWarn< "incompatible operand types (%0 and %1)">; def err_cond_voidptr_arc : Error < @@ -4026,7 +4105,7 @@ def err_typecheck_comparison_of_distinct_pointers : Error< "comparison of distinct pointer types%diff{ ($ and $)|}0,1">; def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn< "comparison of distinct pointer types (%0 and %1) uses non-standard " - "composite pointer type %2">; + "composite pointer type %2">, InGroup<CompareDistinctPointerType>; def err_typecheck_assign_const : Error<"read-only variable is not assignable">; def err_stmtexpr_file_scope : Error< "statement expression not allowed at file scope">; @@ -4036,6 +4115,9 @@ def warn_mixed_sign_comparison : Warning< def warn_lunsigned_always_true_comparison : Warning< "comparison of unsigned%select{| enum}2 expression %0 is always %1">, InGroup<TautologicalCompare>; +def warn_out_of_range_compare : Warning< + "comparison of constant %0 with expression of type %1 is always " + "%select{false|true}2">, InGroup<TautologicalOutOfRangeCompare>; def warn_runsigned_always_true_comparison : Warning< "comparison of %0 unsigned%select{| enum}2 expression is always %1">, InGroup<TautologicalCompare>; @@ -4169,7 +4251,7 @@ def err_nogetter_property_incdec : Error< 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'">; + "%select{property|instance variable}0 access cannot be qualified with '%1'">; def ext_freestanding_complex : Extension< "complex numbers are an extension in a freestanding C99 implementation">; @@ -4565,7 +4647,7 @@ def err_invalid_declarator_global_scope : Error< def err_invalid_declarator_in_function : Error< "definition or redeclaration of %0 not allowed inside a function">; def err_not_tag_in_scope : Error< - "no %select{struct|union|class|enum}0 named %1 in %2">; + "no %select{struct|interface|union|class|enum}0 named %1 in %2">; def err_no_typeid_with_fno_rtti : Error< "cannot use typeid with -fno-rtti">; @@ -4888,6 +4970,8 @@ def note_callee_decl : Note< "%0 declared here">; def note_defined_here : Note<"%0 defined here">; +def err_builtin_fn_use : Error<"builtin functions must be directly called">; + 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< @@ -4901,6 +4985,9 @@ def err_atomic_builtin_pointer_size : Error< 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_non_const_atomic : Error< + "first argument to atomic operation must be a pointer to non-const _Atomic " + "type (%0 invalid)">; def err_atomic_op_needs_trivial_copy : Error< "first argument to atomic operation must be a pointer to a trivially-copyable" " type (%0 invalid)">; @@ -4963,7 +5050,9 @@ def err_typecheck_cast_to_incomplete : Error< "cast to incomplete type %0">; def ext_typecheck_cast_nonscalar : Extension< "C99 forbids casting nonscalar type %0 to the same type">; -def ext_typecheck_cast_to_union : Extension<"C99 forbids casts to union type">; +def ext_typecheck_cast_to_union : Extension< + "cast to union type is a GNU extension">, + InGroup<GNU>; def err_typecheck_cast_to_union_no_type : Error< "cast to union type from type %0 not present in union">; def err_cast_pointer_from_non_pointer_int : Error< @@ -4971,6 +5060,9 @@ def err_cast_pointer_from_non_pointer_int : Error< def warn_cast_pointer_from_sel : Warning< "cast of type %0 to %1 is deprecated; use sel_getName instead">, InGroup<SelTypeCast>; +def warn_bad_function_cast : Warning< + "cast from function call of type %0 to non-matching type %1">, + InGroup<BadFunctionCast>, DefaultIgnore; def err_cast_pointer_to_non_pointer_int : Error< "pointer cannot be cast to type %0">; def err_typecheck_expect_scalar_operand : Error< @@ -5048,19 +5140,21 @@ let CategoryName = "Inline Assembly Issue" in { "unsupported inline asm: input with type " "%diff{$ matching output with type $|}0,1">; def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">; - def warn_asm_label_on_auto_decl : Warning< - "ignored asm label '%0' on automatic variable">; + def err_asm_empty : Error<"__asm used with no assembly instructions">; def err_invalid_asm_cast_lvalue : Error< "invalid use of a cast in a inline asm context requiring an l-value: " "remove the cast or build with -fheinous-gnu-extensions">; + def err_inline_ms_asm_parsing : Error<"%0">; + def warn_asm_label_on_auto_decl : Warning< + "ignored asm label '%0' on automatic variable">; def warn_invalid_asm_cast_lvalue : Warning< - "invalid use of a cast in a inline asm context requiring an l-value: " + "invalid use of a cast in an inline asm context requiring an l-value: " "accepted due to -fheinous-gnu-extensions, but clang may remove support " "for this in the future">; - - def warn_unsupported_msasm : ExtWarn< - "MS-style inline assembly is not supported">, InGroup<Microsoft>; + def warn_asm_mismatched_size_modifier : Warning< + "the size being stored is truncated, use a modifier to specify the size">, + InGroup<ASMOperandWidths>; } let CategoryName = "Semantic Issue" in { @@ -5125,7 +5219,7 @@ def err_in_class_initializer_references_def_ctor : Error< def ext_in_class_initializer_non_constant : Extension< "in-class initializer for static data member is not a constant expression; " - "folding it to a constant is a GNU extension">; + "folding it to a constant is a GNU extension">, InGroup<GNU>; // C++ anonymous unions and GNU anonymous structs/unions def ext_anonymous_union : Extension< @@ -5181,6 +5275,8 @@ def err_static_data_member_not_allowed_in_local_class : Error< def err_base_clause_on_union : Error<"unions cannot have base classes">; def err_base_must_be_class : Error<"base specifier must name a class">; def err_union_as_base_class : Error<"unions cannot be base classes">; +def err_circular_inheritance : Error< + "circular inheritance between %0 and %1">; def err_incomplete_base_class : Error<"base class has incomplete type">; def err_duplicate_base_class : Error< "base class %0 specified more than once as a direct base class">; @@ -5343,6 +5439,10 @@ 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 ext_implicit_exception_spec_mismatch : ExtWarn< + "function previously declared with an %select{explicit|implicit}0 exception " + "specification redeclared with an %select{implicit|explicit}0 exception " + "specification">, InGroup<DiagGroup<"implicit-exception-spec-mismatch">>; def warn_ptr_arith_precedes_bounds : Warning< "the pointer decremented by %0 refers before the beginning of the array">, @@ -5376,6 +5476,10 @@ def warn_scanf_nonzero_width : Warning< def warn_printf_conversion_argument_type_mismatch : Warning< "format specifies type %0 but the argument has type %1">, InGroup<Format>; +def warn_format_argument_needs_cast : Warning< + "values of type '%0' should not be used as format arguments; add an explicit " + "cast to %1 instead">, + InGroup<Format>; def warn_printf_positional_arg_exceeds_data_args : Warning < "data argument position '%0' exceeds the number of data arguments (%1)">, InGroup<Format>; @@ -5400,7 +5504,8 @@ def warn_format_string_is_wide_literal : Warning< def warn_printf_format_string_contains_null_char : Warning< "format string contains '\\0' within the string body">, InGroup<Format>; def warn_printf_asterisk_missing_arg : Warning< - "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">; + "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">, + InGroup<Format>; def warn_printf_asterisk_wrong_type : Warning< "field %select{width|precision}0 should have type %1, but argument has type %2">, InGroup<Format>; @@ -5428,6 +5533,7 @@ def warn_scanf_scanlist_incomplete : Warning< "no closing ']' for '%%[' in scanf format string">, InGroup<Format>; def note_format_string_defined : Note<"format string is defined here">; +def note_format_fix_specifier : Note<"did you mean to use '%0'?">; def note_printf_c_str: Note<"did you mean to call the %0 method?">; def warn_null_arg : Warning< @@ -5591,7 +5697,7 @@ def warn_unannotated_fallthrough_per_function : Warning< "unannotated fall-through between switch labels in partly-annotated " "function">, InGroup<ImplicitFallthroughPerFunction>, DefaultIgnore; def note_insert_fallthrough_fixit : Note< - "insert '[[clang::fallthrough]];' to silence this warning">; + "insert '%0;' to silence this warning">; def note_insert_break_fixit : Note< "insert 'break;' to avoid fall-through">; def err_fallthrough_attr_wrong_target : Error< @@ -5827,7 +5933,7 @@ def err_typecheck_member_reference_ivar_suggest : Error< def err_property_not_found_suggest : Error< "property %0 not found on object of type %1; did you mean %2?">; def err_ivar_access_using_property_syntax_suggest : Error< - "property %0 not found on object of type %1; did you mean to access ivar %2?">; + "property %0 not found on object of type %1; did you mean to access instance variable %2?">; def err_property_found_suggest : Error< "property %0 found on object of type %1; did you mean to access " "it with the \".\" operator?">; @@ -5914,7 +6020,7 @@ 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 " + "local %select{struct|interface|union|class|enum}0 cannot be declared " "__module_private__">; def err_module_private_definition : Error< "definition of %0 must be imported before it is required">; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td index a440e80..e9df09d 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td @@ -25,9 +25,13 @@ def err_fe_pch_file_modified : Error< def err_fe_pch_file_overridden : Error< "file '%0' from the precompiled header has been overridden">; -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 err_pch_targetopt_mismatch : Error< + "PCH file was compiled for the %0 '%1' but the current translation " + "unit is being compiled for target '%2'">; +def err_pch_targetopt_feature_mismatch : Error< + "%select{AST file|current translation unit}0 was compiled with the target " + "feature'%1' but the %select{current translation unit is|AST file was}0 " + "not">; 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< @@ -41,21 +45,24 @@ def warn_pch_different_branch : Error< "PCH file built from a different branch (%0) than the compiler (%1)">; def err_pch_with_compiler_errors : Error< "PCH file contains compiler errors">; -def warn_cmdline_conflicting_macro_def : Error< - "definition of the macro '%0' conflicts with the definition used to " - "build the precompiled header">; -def note_pch_macro_defined_as : Note< - "definition of macro '%0' in the precompiled header">; -def warn_cmdline_missing_macro_defs : Warning< - "macro definitions used to build the precompiled header are missing">; -def note_using_macro_def_from_pch : Note< - "using this macro definition from precompiled header">; -def warn_macro_name_used_in_pch : Error< - "definition of macro %0 conflicts with an identifier used in the " - "precompiled header">; -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 err_pch_macro_def_undef : Error< + "macro '%0' was %select{defined|undef'd}1 in the precompiled header but " + "%select{undef'd|defined}1 on the command line">; +def err_pch_macro_def_conflict : Error< + "definition of macro '%0' differs between the precompiled header ('%1') " + "and the command line ('%2')">; +def err_pch_include_opt_missing : Error< + "precompiled header depends on '%select{-include|-imacros}0 %1' option " + "that is missing from the command line">; +def err_pch_include_opt_conflict : Error< + "precompiled header option '%select{-include|-imacros}0 %1' conflicts with " + "corresponding option '%select{-include|-imacros}0 %2' on command line">; +def err_pch_undef : Error< + "%select{command line contains|precompiled header was built with}0 " + "'-undef' but %select{precompiled header was not built with it|" + "it is not present on the command line}0">; def err_not_a_pch_file : Error< "'%0' does not appear to be a precompiled header file">, DefaultFatal; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h index b00f2b7..b2f578d 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h @@ -103,6 +103,10 @@ public: bool operator<(const FileEntry &RHS) const { return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode); } + + /// \brief Check whether the file is a named pipe (and thus can't be opened by + /// the native FileManager methods). + bool isNamedPipe() const; }; /// \brief Implements support for file system lookup, file system caching, diff --git a/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h index dc6acda..76242ec 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h @@ -21,7 +21,6 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <cassert> #include <string> @@ -54,6 +53,7 @@ class IdentifierInfo { // are for builtins. unsigned ObjCOrBuiltinID :11; bool HasMacro : 1; // True if there is a #define for this. + bool HadMacro : 1; // True if there was 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. @@ -70,13 +70,13 @@ class IdentifierInfo { // stored externally. bool IsModulesImport : 1; // True if this is the 'import' contextual // keyword. - // 1 bit left in 32-bit word. - + // 32-bit word is filled. + void *FETokenInfo; // Managed by the language front-end. llvm::StringMapEntry<IdentifierInfo*> *Entry; - IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE. - void operator=(const IdentifierInfo&); // NONASSIGNABLE. + IdentifierInfo(const IdentifierInfo&) LLVM_DELETED_FUNCTION; + void operator=(const IdentifierInfo&) LLVM_DELETED_FUNCTION; friend class IdentifierTable; @@ -133,10 +133,21 @@ public: if (HasMacro == Val) return; HasMacro = Val; - if (Val) + if (Val) { NeedsHandleIdentifier = 1; - else + HadMacro = true; + } else { RecomputeNeedsHandleIdentifier(); + } + } + /// \brief Returns true if this identifier was \#defined to some value at any + /// moment. In this case there should be an entry for the identifier in the + /// macro history table in Preprocessor. + bool hadMacroDefinition() const { + return HadMacro; + } + void setHadMacroDefinition(bool Val) { + HadMacro = Val; } /// getTokenID - If this is a source-language token (e.g. 'for'), this API @@ -346,8 +357,8 @@ public: /// actual functionality. class IdentifierIterator { private: - IdentifierIterator(const IdentifierIterator&); // Do not implement - IdentifierIterator &operator=(const IdentifierIterator&); // Do not implement + IdentifierIterator(const IdentifierIterator &) LLVM_DELETED_FUNCTION; + void operator=(const IdentifierIterator &) LLVM_DELETED_FUNCTION; protected: IdentifierIterator() { } @@ -695,8 +706,8 @@ public: /// multi-keyword caching. class SelectorTable { void *Impl; // Actually a SelectorTableImpl - SelectorTable(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT - void operator=(const SelectorTable&); // DISABLED: DO NOT IMPLEMENT + SelectorTable(const SelectorTable &) LLVM_DELETED_FUNCTION; + void operator=(const SelectorTable &) LLVM_DELETED_FUNCTION; public: SelectorTable(); ~SelectorTable(); diff --git a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def index 76de1e8..571b9d2 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def @@ -48,15 +48,19 @@ 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(CPlusPlus1y , 1, 0, "C++1y") LANGOPT(ObjC1 , 1, 0, "Objective-C 1") LANGOPT(ObjC2 , 1, 0, "Objective-C 2") BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, "Objective-C auto-synthesized properties") +BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0, + "Encoding extended block type signature") BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1, "Objective-C related result type inference") LANGOPT(Trigraphs , 1, 0,"trigraphs") -LANGOPT(BCPLComment , 1, 0, "BCPL-style '//' comments") +LANGOPT(LineComment , 1, 0, "'//' comments") LANGOPT(Bool , 1, 0, "bool, true, and false keywords") +LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword") BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers") BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode") BENIGN_LANGOPT(GNUMode , 1, 1, "GNU extensions") @@ -116,7 +120,6 @@ 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(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form") BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables") @@ -126,8 +129,6 @@ BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype") BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support") BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type") BENIGN_LANGOPT(DebuggerObjCLiteral , 1, 0, "debugger Objective-C literals and subscripting support") -BENIGN_LANGOPT(AddressSanitizer , 1, 0, "AddressSanitizer enabled") -BENIGN_LANGOPT(ThreadSanitizer , 1, 0, "ThreadSanitizer enabled") BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking") LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants") @@ -136,7 +137,7 @@ LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT") LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment") LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility") LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting") -LANGOPT(ObjCRuntimeHasWeak , 1, 0, "__weak support in the ARC runtime") +LANGOPT(ObjCARCWeak , 1, 0, "__weak support in the ARC runtime") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") LANGOPT(MRTD , 1, 0, "-mrtd calling convention") @@ -163,6 +164,17 @@ VALUE_LANGOPT(MSCVersion, 32, 0, LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling") +BENIGN_LANGOPT(EmitMicrosoftInlineAsm , 1, 0, + "Enable emission of MS-style inline assembly.") + + +BENIGN_LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST") + +/// Runtime sanitizers. +#define SANITIZER(NAME, ID) \ +BENIGN_LANGOPT(Sanitize##ID, 1, 0, NAME " sanitizer") +#include "clang/Basic/Sanitizers.def" + #undef LANGOPT #undef VALUE_LANGOPT #undef BENIGN_LANGOPT diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Module.h b/contrib/llvm/tools/clang/include/clang/Basic/Module.h index c8027f4..b6b088c 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Module.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Module.h @@ -21,6 +21,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SetVector.h" #include <string> #include <utility> #include <vector> @@ -63,11 +64,21 @@ private: /// \brief A mapping from the submodule name to the index into the /// \c SubModules vector at which that submodule resides. llvm::StringMap<unsigned> SubModuleIndex; + + /// \brief The AST file if this is a top-level module which has a + /// corresponding serialized AST file, or null otherwise. + const FileEntry *ASTFile; public: /// \brief The headers that are part of this module. llvm::SmallVector<const FileEntry *, 2> Headers; + /// \brief The headers that are explicitly excluded from this module. + llvm::SmallVector<const FileEntry *, 2> ExcludedHeaders; + + /// \brief The top-level headers associated with this module. + llvm::SmallSetVector<const FileEntry *, 2> TopHeaders; + /// \brief The set of language features required to use this module. /// /// If any of these features is not present, the \c IsAvailable bit @@ -158,7 +169,7 @@ public: /// \brief Construct a top-level module. explicit Module(StringRef Name, SourceLocation DefinitionLoc, bool IsFramework) - : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0), Umbrella(), + : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0),Umbrella(),ASTFile(0), IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(false), IsSystem(false), InferSubmodules(false), InferExplicitSubmodules(false), @@ -227,7 +238,18 @@ public: StringRef getTopLevelModuleName() const { return getTopLevelModule()->Name; } - + + /// \brief The serialized AST file for this module, if one was created. + const FileEntry *getASTFile() const { + return getTopLevelModule()->ASTFile; + } + + /// \brief Set the serialized AST file for the top-level module of this module. + void setASTFile(const FileEntry *File) { + assert((getASTFile() == 0 || getASTFile() == File) && "file path changed"); + getTopLevelModule()->ASTFile = File; + } + /// \brief Retrieve the directory for which this module serves as the /// umbrella. const DirectoryEntry *getUmbrellaDir() const; @@ -271,6 +293,10 @@ public: submodule_iterator submodule_end() { return SubModules.end(); } submodule_const_iterator submodule_end() const { return SubModules.end(); } + static StringRef getModuleInputBufferName() { + return "<module-includes>"; + } + /// \brief Print the module map for this module to the given stream. /// void print(llvm::raw_ostream &OS, unsigned Indent = 0) const; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h b/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h index b24fe7c..d543b76 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h @@ -126,12 +126,25 @@ public: return !isGNUFamily(); } + /// \brief Does this runtime allow ARC at all? + bool allowsARC() const { + switch (getKind()) { + case FragileMacOSX: return false; + case MacOSX: return true; + case iOS: return true; + case GCC: return false; + case GNUstep: return true; + case ObjFW: return true; + } + llvm_unreachable("bad kind"); + } + /// \brief Does this runtime natively provide the ARC entrypoints? /// /// ARC cannot be directly supported on a platform that does not provide /// these entrypoints, although it may be supportable via a stub /// library. - bool hasARC() const { + bool hasNativeARC() const { switch (getKind()) { case FragileMacOSX: return false; case MacOSX: return getVersion() >= VersionTuple(10, 7); @@ -139,16 +152,35 @@ public: case GCC: return false; case GNUstep: return getVersion() >= VersionTuple(1, 6); - case ObjFW: return false; // XXX: this will change soon + case ObjFW: return true; } llvm_unreachable("bad kind"); } + /// \brief Does this runtime supports optimized setter entrypoints? + bool hasOptimizedSetter() const { + switch (getKind()) { + case MacOSX: + return getVersion() >= VersionTuple(10, 8); + case iOS: + return (getVersion() >= VersionTuple(6)); + + default: + return false; + } + } + + /// Does this runtime allow the use of __weak? + bool allowsWeak() const { + return hasNativeWeak(); + } + /// \brief Does this runtime natively provide ARC-compliant 'weak' /// entrypoints? - bool hasWeak() const { - // Right now, this is always equivalent to the ARC decision. - return hasARC(); + bool hasNativeWeak() const { + // Right now, this is always equivalent to whether the runtime + // natively supports ARC decision. + return hasNativeARC(); } /// \brief Does this runtime directly support the subscripting methods? @@ -158,7 +190,7 @@ public: switch (getKind()) { case FragileMacOSX: return false; case MacOSX: return getVersion() >= VersionTuple(10, 8); - case iOS: return false; + case iOS: return getVersion() >= VersionTuple(6); // This is really a lie, because some implementations and versions // of the runtime do not support ARC. Probably -fgnu-runtime @@ -226,6 +258,7 @@ public: } llvm_unreachable("bad kind"); } + /// \brief Does this runtime use zero-cost exceptions? bool hasUnwindExceptions() const { switch (getKind()) { diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h b/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h index 79273fc..cc9ca9f 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/OnDiskHashTable.h @@ -65,8 +65,7 @@ inline void Emit64(raw_ostream& Out, uint64_t V) { 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) + for (uint32_t n = llvm::OffsetToAlignment(off, A); n; --n) Emit8(Out, 0); } @@ -102,7 +101,7 @@ inline uint64_t ReadUnalignedLE64(const unsigned char *&Data) { inline uint32_t ReadLE32(const unsigned char *&Data) { // Hosts that directly support little-endian 32-bit loads can just // use them. Big-endian hosts need a bswap. - uint32_t V = *((uint32_t*)Data); + uint32_t V = *((const uint32_t*)Data); if (llvm::sys::isBigEndianHost()) V = llvm::ByteSwap_32(V); Data += 4; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def b/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def new file mode 100644 index 0000000..085ca16 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def @@ -0,0 +1,69 @@ +//===--- Sanitizers.def - Runtime sanitizer options -------------*- 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 options for specifying which runtime sanitizers to +// enable. Users of this file must define the SANITIZER macro to make use of +// this information. Users of this file can also define the SANITIZER_GROUP +// macro to get information on options which refer to sets of sanitizers. +// +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER +#error "Define SANITIZER prior to including this file!" +#endif + +// SANITIZER(NAME, ID) + +// The first value is the name of the sanitizer as a string. The sanitizer can +// be enabled by specifying -fsanitize=NAME. + +// The second value is an identifier which can be used to refer to the +// sanitizer. + + +// SANITIZER_GROUP(NAME, ID, ALIAS) + +// The first two values have the same semantics as the corresponding SANITIZER +// values. The third value is an expression ORing together the IDs of individual +// sanitizers in this group. + +#ifndef SANITIZER_GROUP +#define SANITIZER_GROUP(NAME, ID, ALIAS) +#endif + + +// AddressSanitizer +SANITIZER("address", Address) + +// ThreadSanitizer +SANITIZER("thread", Thread) + +// UndefinedBehaviorSanitizer +SANITIZER("signed-integer-overflow", SignedIntegerOverflow) +SANITIZER("divide-by-zero", DivideByZero) +SANITIZER("shift", Shift) +SANITIZER("unreachable", Unreachable) +SANITIZER("return", Return) +SANITIZER("vla-bound", VLABound) +SANITIZER("alignment", Alignment) +SANITIZER("null", Null) +SANITIZER("vptr", Vptr) +SANITIZER("object-size", ObjectSize) +SANITIZER("float-cast-overflow", FloatCastOverflow) + +// -fsanitize=undefined (and its alias -fcatch-undefined-behavior). This should +// include all the sanitizers which have low overhead, no ABI or address space +// layout implications, and only catch undefined behavior. +SANITIZER_GROUP("undefined", Undefined, + SignedIntegerOverflow | DivideByZero | Shift | Unreachable | + Return | VLABound | Alignment | Null | Vptr | ObjectSize | + FloatCastOverflow) + +#undef SANITIZER +#undef SANITIZER_GROUP diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h index d6bba38..cfcf468 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h @@ -21,6 +21,7 @@ #include <utility> #include <functional> #include <cassert> +#include <string> namespace llvm { class MemoryBuffer; @@ -171,6 +172,7 @@ public: } void print(raw_ostream &OS, const SourceManager &SM) const; + LLVM_ATTRIBUTE_USED std::string printToString(const SourceManager &SM) const; void dump(const SourceManager &SM) const; }; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h index 32268d7..db6bfd2 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h @@ -62,7 +62,6 @@ class LangOptions; class ASTWriter; class ASTReader; -/// \namespace /// \brief Public enums and private classes that are part of the /// SourceManager implementation. /// @@ -221,7 +220,7 @@ namespace SrcMgr { private: // Disable assignments. - ContentCache &operator=(const ContentCache& RHS); + ContentCache &operator=(const ContentCache& RHS) LLVM_DELETED_FUNCTION; }; /// \brief Information about a FileID, basically just the logical file @@ -647,8 +646,8 @@ class SourceManager : public RefCountedBase<SourceManager> { mutable llvm::DenseMap<FileID, MacroArgsMap *> MacroArgsCacheMap; // SourceManager doesn't support copy construction. - explicit SourceManager(const SourceManager&); - void operator=(const SourceManager&); + explicit SourceManager(const SourceManager&) LLVM_DELETED_FUNCTION; + void operator=(const SourceManager&) LLVM_DELETED_FUNCTION; public: SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, bool UserFilesAreVolatile = false); @@ -675,9 +674,10 @@ public: /// /// One example of when this would be used is when the main source is read /// from STDIN. - FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { + FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer, + SrcMgr::CharacteristicKind Kind = SrcMgr::C_User) { assert(MainFileID.isInvalid() && "MainFileID already set!"); - MainFileID = createFileIDForMemBuffer(Buffer); + MainFileID = createFileIDForMemBuffer(Buffer, Kind); return MainFileID; } @@ -734,10 +734,11 @@ public: /// 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, + SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User, int LoadedID = 0, unsigned LoadedOffset = 0, SourceLocation IncludeLoc = SourceLocation()) { return createFileID(createMemBufferContentCache(Buffer), IncludeLoc, - SrcMgr::C_User, LoadedID, LoadedOffset); + FileCharacter, LoadedID, LoadedOffset); } /// \brief Return a new SourceLocation that encodes the @@ -1557,7 +1558,11 @@ private: getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, unsigned Offset) const; void computeMacroArgsCache(MacroArgsMap *&MacroArgsCache, FileID FID) const; - + void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache, + FileID FID, + SourceLocation SpellLoc, + SourceLocation ExpansionLoc, + unsigned ExpansionLength) const; friend class ASTReader; friend class ASTWriter; }; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h index 96cada1..c82b8cb 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h @@ -53,6 +53,7 @@ namespace clang { TST_union, TST_struct, TST_class, // C++ class type + TST_interface, // C++ (Microsoft-specific) __interface type TST_typename, // Typedef, C++ class-name or enum name, etc. TST_typeofType, TST_typeofExpr, @@ -174,6 +175,20 @@ namespace clang { ICIS_CopyInit, ///< Copy initialization. ICIS_ListInit ///< Direct list-initialization. }; + + /// \brief CallingConv - Specifies the calling convention that a function uses. + enum CallingConv { + CC_Default, + CC_C, // __attribute__((cdecl)) + CC_X86StdCall, // __attribute__((stdcall)) + CC_X86FastCall, // __attribute__((fastcall)) + CC_X86ThisCall, // __attribute__((thiscall)) + CC_X86Pascal, // __attribute__((pascal)) + CC_AAPCS, // __attribute__((pcs("aapcs"))) + CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp"))) + CC_PnaclCall // __attribute__((pnaclcall)) + }; + } // end namespace clang #endif // LLVM_CLANG_BASIC_SPECIFIERS_H diff --git a/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td b/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td index 47738af..8f6a1c9 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td @@ -28,11 +28,10 @@ def SwitchCase : Stmt<1>; def CaseStmt : DStmt<SwitchCase>; def DefaultStmt : DStmt<SwitchCase>; -// GNU Extensions -def AsmStmt : Stmt; - -// MS Extensions -def MSAsmStmt : Stmt; +// Asm statements +def AsmStmt : Stmt<1>; +def GCCAsmStmt : DStmt<AsmStmt>; +def MSAsmStmt : DStmt<AsmStmt>; // Obj-C statements def ObjCAtTryStmt : Stmt; @@ -132,6 +131,7 @@ def PackExpansionExpr : DStmt<Expr>; def SizeOfPackExpr : DStmt<Expr>; def SubstNonTypeTemplateParmExpr : DStmt<Expr>; def SubstNonTypeTemplateParmPackExpr : DStmt<Expr>; +def FunctionParmPackExpr : DStmt<Expr>; def MaterializeTemporaryExpr : DStmt<Expr>; def LambdaExpr : 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 54d49e6..2d26783 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h @@ -23,7 +23,9 @@ #include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" #include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/TargetOptions.h" #include "clang/Basic/VersionTuple.h" +#include "clang/Basic/Specifiers.h" #include <cassert> #include <vector> #include <string> @@ -38,7 +40,6 @@ class LangOptions; class MacroBuilder; class SourceLocation; class SourceManager; -class TargetOptions; namespace Builtin { struct Info; } @@ -61,6 +62,7 @@ enum TargetCXXABI { /// \brief Exposes information about the current target. /// class TargetInfo : public RefCountedBase<TargetInfo> { + llvm::IntrusiveRefCntPtr<TargetOptions> TargetOpts; llvm::Triple Triple; protected: // Target values set by the ctor of the actual target implementation. Default @@ -111,6 +113,16 @@ public: virtual ~TargetInfo(); + /// \brief Retrieve the target options. + TargetOptions &getTargetOpts() const { + assert(TargetOpts && "Missing target options"); + return *TargetOpts; + } + + void setTargetOpts(TargetOptions &TargetOpts) { + this->TargetOpts = &TargetOpts; + } + ///===---- Target Data Type Query Methods -------------------------------===// enum IntType { NoInt = 0, @@ -150,12 +162,18 @@ public: /// __builtin_va_list as defined by the x86-64 ABI: /// http://www.x86-64.org/documentation/abi.pdf - X86_64ABIBuiltinVaList + X86_64ABIBuiltinVaList, + + /// __builtin_va_list as defined by ARM AAPCS ABI + /// http://infocenter.arm.com + // /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf + AAPCSABIBuiltinVaList }; protected: IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType, - WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType; + WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType, + ProcessIDType; /// \brief Whether Objective-C's built-in boolean type should be signed char. /// @@ -196,7 +214,7 @@ public: IntType getChar32Type() const { return Char32Type; } IntType getInt64Type() const { return Int64Type; } IntType getSigAtomicType() const { return SigAtomicType; } - + IntType getProcessIDType() const { return ProcessIDType; } /// \brief Return the width (in bits) of the specified integer type enum. /// @@ -500,6 +518,11 @@ public: bool validateInputConstraint(ConstraintInfo *OutputConstraints, unsigned NumOutputs, ConstraintInfo &info) const; + virtual bool validateConstraintModifier(StringRef /*Constraint*/, + const char /*Modifier*/, + unsigned /*Size*/) const { + return true; + } bool resolveSymbolicName(const char *&Name, ConstraintInfo *OutputConstraints, unsigned NumOutputs, unsigned &Index) const; @@ -712,6 +735,34 @@ public: bool isBigEndian() const { return BigEndian; } + /// \brief Gets the default calling convention for the given target and + /// declaration context. + virtual CallingConv getDefaultCallingConv() const { + // Not all targets will specify an explicit calling convention that we can + // express. This will always do the right thing, even though it's not + // an explicit calling convention. + return CC_Default; + } + + enum CallingConvCheckResult { + CCCR_OK, + CCCR_Warning + }; + + /// \brief Determines whether a given calling convention is valid for the + /// target. A calling convention can either be accepted, produce a warning + /// and be substituted with the default calling convention, or (someday) + /// produce an error (such as using thiscall on a non-instance function). + virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { + switch (CC) { + default: + return CCCR_Warning; + case CC_C: + case CC_Default: + return CCCR_OK; + } + } + protected: virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return PointerWidth; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h index 15ececd..d6deb02 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h @@ -15,13 +15,14 @@ #ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H #define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include <string> #include <vector> namespace clang { /// \brief Options for controlling the target. -class TargetOptions { +class TargetOptions : public RefCountedBase<TargetOptions> { public: /// If given, the name of the target triple to compile for. If not given the /// target will be selected to match the host. @@ -40,6 +41,9 @@ public: /// If given, the version string of the linker in use. std::string LinkerVersion; + /// \brief The list of target specific features to enable or disable, as written on the command line. + std::vector<std::string> FeaturesAsWritten; + /// The list of target specific features to enable or disable -- this should /// be a list of strings starting with by '+' or '-'. std::vector<std::string> Features; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def index fc03191..25e8d5a 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def @@ -217,6 +217,7 @@ PUNCTUATOR(greatergreatergreater, ">>>") // KEYALTIVEC - This is a keyword in AltiVec // KEYBORLAND - This is a keyword if Borland extensions are enabled // BOOLSUPPORT - This is a keyword if 'bool' is a built-in type +// WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type // KEYWORD(auto , KEYALL) KEYWORD(break , KEYALL) @@ -295,7 +296,7 @@ KEYWORD(typename , KEYCXX) KEYWORD(typeid , KEYCXX) KEYWORD(using , KEYCXX) KEYWORD(virtual , KEYCXX) -KEYWORD(wchar_t , KEYCXX) +KEYWORD(wchar_t , WCHARSUPPORT) // C++ 2.5p2: Alternative Representations. CXX_KEYWORD_OPERATOR(and , ampamp) @@ -364,6 +365,7 @@ KEYWORD(__is_convertible_to , KEYCXX) KEYWORD(__is_empty , KEYCXX) KEYWORD(__is_enum , KEYCXX) KEYWORD(__is_final , KEYCXX) +KEYWORD(__is_interface_class , KEYCXX) // Tentative name - there's no implementation of std::is_literal_type yet. KEYWORD(__is_literal , KEYCXX) // Name for GCC 4.6 compatibility - people have already written libraries using @@ -505,6 +507,7 @@ KEYWORD(__if_not_exists , KEYMS) KEYWORD(__single_inheritance , KEYMS) KEYWORD(__multiple_inheritance , KEYMS) KEYWORD(__virtual_inheritance , KEYMS) +KEYWORD(__interface , KEYMS) ALIAS("__int8" , char , KEYMS) ALIAS("__int16" , short , KEYMS) ALIAS("__int32" , int , KEYMS) @@ -518,7 +521,6 @@ ALIAS("_thiscall" , __thiscall , KEYMS) ALIAS("_uuidof" , __uuidof , KEYMS | KEYBORLAND) ALIAS("_inline" , inline , KEYMS) ALIAS("_declspec" , __declspec , KEYMS) -ALIAS("__interface" , struct , KEYMS) // Borland Extensions which should be disabled in strict conformance mode. ALIAS("_pascal" , __pascal , KEYBORLAND) @@ -600,6 +602,41 @@ ANNOTATION(pragma_pack) // handles them. ANNOTATION(pragma_parser_crash) +// Annotation for #pragma ms_struct... +// The lexer produces these so that they only take effect when the parser +// handles them. +ANNOTATION(pragma_msstruct) + +// Annotation for #pragma align... +// The lexer produces these so that they only take effect when the parser +// handles them. +ANNOTATION(pragma_align) + +// Annotation for #pragma weak id +// The lexer produces these so that they only take effect when the parser +// handles them. +ANNOTATION(pragma_weak) + +// Annotation for #pragma weak id = id +// The lexer produces these so that they only take effect when the parser +// handles them. +ANNOTATION(pragma_weakalias) + +// Annotation for #pragma redefine_extname... +// The lexer produces these so that they only take effect when the parser +// handles them. +ANNOTATION(pragma_redefine_extname) + +// Annotation for #pragma STDC FP_CONTRACT... +// The lexer produces these so that they only take effect when the parser +// handles them. +ANNOTATION(pragma_fp_contract) + +// Annotation for #pragma OPENCL EXTENSION... +// The lexer produces these so that they only take effect when the parser +// handles them. +ANNOTATION(pragma_opencl_extension) + #undef ANNOTATION #undef TESTING_KEYWORD #undef OBJC2_AT_KEYWORD diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.h b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.h index 478add8..e850971 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.h @@ -63,6 +63,31 @@ const char *getTokenName(enum TokenKind Kind); /// Preprocessor::getSpelling(). const char *getTokenSimpleSpelling(enum TokenKind Kind); +/// \brief Return true if this is a raw identifier or an identifier kind. +inline bool isAnyIdentifier(TokenKind K) { + return (K == tok::identifier) || (K == tok::raw_identifier); +} + +/// \brief Return true if this is a "literal" kind, like a numeric +/// constant, string, etc. +inline bool isLiteral(TokenKind K) { + return (K == tok::numeric_constant) || (K == tok::char_constant) || + (K == tok::wide_char_constant) || (K == tok::utf16_char_constant) || + (K == tok::utf32_char_constant) || (K == tok::string_literal) || + (K == tok::wide_string_literal) || (K == tok::utf8_string_literal) || + (K == tok::utf16_string_literal) || (K == tok::utf32_string_literal) || + (K == tok::angle_string_literal); +} + +/// \brief Return true if this is any of tok::annot_* kinds. +inline bool isAnnotation(TokenKind K) { +#define ANNOTATION(NAME) \ + if (K == tok::annot_##NAME) \ + return true; +#include "clang/Basic/TokenKinds.def" + return false; +} + } // end namespace tok } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h b/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h index 0a5a864..882b52d 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h @@ -41,6 +41,7 @@ namespace clang { UTT_IsFunction, UTT_IsFundamental, UTT_IsIntegral, + UTT_IsInterfaceClass, UTT_IsLiteral, UTT_IsLvalueReference, UTT_IsMemberFunctionPointer, diff --git a/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td b/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td index 451d562..3373e01 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td @@ -379,8 +379,8 @@ def VORR : Inst<"vorr", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_OR>; def VEOR : Inst<"veor", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_XOR>; def VBIC : Inst<"vbic", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ANDN>; def VORN : Inst<"vorn", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ORN>; -def VBSL : Inst<"vbsl", "dudd", - "csilUcUsUiUlfPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPs", OP_SEL>; +def VBSL : SInst<"vbsl", "dudd", + "csilUcUsUiUlfPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPs">; //////////////////////////////////////////////////////////////////////////////// // E.3.30 Transposition operations @@ -394,3 +394,7 @@ def VREINTERPRET : Inst<"vreinterpret", "dd", "csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs", OP_REINT>; +//////////////////////////////////////////////////////////////////////////////// +// Vector fused multiply-add operations + +def VFMA : SInst<"vfma", "dddd", "fQf">; diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h index 7fa589f..912ef01 100644 --- a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h @@ -30,7 +30,7 @@ private: bool OwnsVMContext; protected: - /// Create a new code generation action. If the optional \arg _VMContext + /// Create a new code generation action. If the optional \p _VMContext /// parameter is supplied, the action uses it without taking ownership, /// otherwise it creates a fresh LLVM context and takes ownership. CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = 0); diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Action.h b/contrib/llvm/tools/clang/include/clang/Driver/Action.h index 6e317a0..4057e48 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Action.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Action.h @@ -90,8 +90,6 @@ public: iterator end() { return Inputs.end(); } const_iterator begin() const { return Inputs.begin(); } const_iterator end() const { return Inputs.end(); } - - static bool classof(const Action *) { return true; } }; class InputAction : public Action { @@ -105,7 +103,6 @@ public: static bool classof(const Action *A) { return A->getKind() == InputClass; } - static bool classof(const InputAction *) { return true; } }; class BindArchAction : public Action { @@ -122,7 +119,6 @@ public: static bool classof(const Action *A) { return A->getKind() == BindArchClass; } - static bool classof(const BindArchAction *) { return true; } }; class JobAction : public Action { @@ -136,7 +132,6 @@ public: return (A->getKind() >= JobClassFirst && A->getKind() <= JobClassLast); } - static bool classof(const JobAction *) { return true; } }; class PreprocessJobAction : public JobAction { @@ -147,7 +142,6 @@ public: static bool classof(const Action *A) { return A->getKind() == PreprocessJobClass; } - static bool classof(const PreprocessJobAction *) { return true; } }; class PrecompileJobAction : public JobAction { @@ -158,7 +152,6 @@ public: static bool classof(const Action *A) { return A->getKind() == PrecompileJobClass; } - static bool classof(const PrecompileJobAction *) { return true; } }; class AnalyzeJobAction : public JobAction { @@ -169,7 +162,6 @@ public: static bool classof(const Action *A) { return A->getKind() == AnalyzeJobClass; } - static bool classof(const AnalyzeJobAction *) { return true; } }; class MigrateJobAction : public JobAction { @@ -180,7 +172,6 @@ public: static bool classof(const Action *A) { return A->getKind() == MigrateJobClass; } - static bool classof(const MigrateJobAction *) { return true; } }; class CompileJobAction : public JobAction { @@ -191,7 +182,6 @@ public: static bool classof(const Action *A) { return A->getKind() == CompileJobClass; } - static bool classof(const CompileJobAction *) { return true; } }; class AssembleJobAction : public JobAction { @@ -202,7 +192,6 @@ public: static bool classof(const Action *A) { return A->getKind() == AssembleJobClass; } - static bool classof(const AssembleJobAction *) { return true; } }; class LinkJobAction : public JobAction { @@ -213,7 +202,6 @@ public: static bool classof(const Action *A) { return A->getKind() == LinkJobClass; } - static bool classof(const LinkJobAction *) { return true; } }; class LipoJobAction : public JobAction { @@ -224,7 +212,6 @@ public: static bool classof(const Action *A) { return A->getKind() == LipoJobClass; } - static bool classof(const LipoJobAction *) { return true; } }; class DsymutilJobAction : public JobAction { @@ -235,7 +222,6 @@ public: static bool classof(const Action *A) { return A->getKind() == DsymutilJobClass; } - static bool classof(const DsymutilJobAction *) { return true; } }; class VerifyJobAction : public JobAction { @@ -245,7 +231,6 @@ public: static bool classof(const Action *A) { return A->getKind() == VerifyJobClass; } - static bool classof(const VerifyJobAction *) { return true; } }; } // end namespace driver diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Arg.h b/contrib/llvm/tools/clang/include/clang/Driver/Arg.h index e466cc3..3b3829a 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Arg.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Arg.h @@ -15,6 +15,8 @@ #ifndef CLANG_DRIVER_ARG_H_ #define CLANG_DRIVER_ARG_H_ +#include "clang/Driver/Option.h" + #include "Util.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -23,7 +25,6 @@ namespace clang { namespace driver { class ArgList; - class Option; /// \brief A concrete instance of a particular driver option. /// @@ -33,17 +34,20 @@ namespace driver { /// ArgList to provide efficient iteration over all instances of a /// particular option. class Arg { - Arg(const Arg &); // DO NOT IMPLEMENT - void operator=(const Arg &); // DO NOT IMPLEMENT + Arg(const Arg &) LLVM_DELETED_FUNCTION; + void operator=(const Arg &) LLVM_DELETED_FUNCTION; private: /// \brief The option this argument is an instance of. - const Option *Opt; + const Option Opt; /// \brief The argument this argument was derived from (during tool chain /// argument translation), if any. const Arg *BaseArg; + /// \brief How this instance of the option was spelled. + StringRef Spelling; + /// \brief The index at which this argument appears in the containing /// ArgList. unsigned Index; @@ -60,14 +64,16 @@ namespace driver { SmallVector<const char *, 2> Values; public: - Arg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0); - Arg(const Option *Opt, unsigned Index, + Arg(const Option Opt, StringRef Spelling, unsigned Index, + const Arg *BaseArg = 0); + Arg(const Option Opt, StringRef Spelling, unsigned Index, const char *Value0, const Arg *BaseArg = 0); - Arg(const Option *Opt, unsigned Index, + Arg(const Option Opt, StringRef Spelling, unsigned Index, const char *Value0, const char *Value1, const Arg *BaseArg = 0); ~Arg(); - const Option &getOption() const { return *Opt; } + const Option getOption() const { return Opt; } + StringRef getSpelling() const { return Spelling; } unsigned getIndex() const { return Index; } /// \brief Return the base argument which generated this arg. @@ -90,7 +96,7 @@ namespace driver { void claim() const { getBaseArg().Claimed = true; } unsigned getNumValues() const { return Values.size(); } - const char *getValue(const ArgList &Args, unsigned N=0) const { + const char *getValue(unsigned N = 0) const { return Values[N]; } @@ -115,8 +121,6 @@ namespace driver { /// when rendered as a input (e.g., Xlinker). void renderAsInput(const ArgList &Args, ArgStringList &Output) const; - static bool classof(const Arg *) { return true; } - void dump() const; /// \brief Return a formatted version of the argument and diff --git a/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h b/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h index b7e490c..72ed7bf 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h @@ -11,6 +11,7 @@ #define CLANG_DRIVER_ARGLIST_H_ #include "clang/Basic/LLVM.h" +#include "clang/Driver/Option.h" #include "clang/Driver/OptSpecifier.h" #include "clang/Driver/Util.h" #include "llvm/ADT/SmallVector.h" @@ -94,8 +95,8 @@ namespace driver { /// and to iterate over groups of arguments. class ArgList { private: - ArgList(const ArgList &); // DO NOT IMPLEMENT - void operator=(const ArgList &); // DO NOT IMPLEMENT + ArgList(const ArgList &) LLVM_DELETED_FUNCTION; + void operator=(const ArgList &) LLVM_DELETED_FUNCTION; public: typedef SmallVector<Arg*, 16> arglist_type; @@ -117,7 +118,7 @@ namespace driver { /// @name Arg Access /// @{ - /// append - Append \arg A to the arg list. + /// append - Append \p A to the arg list. void append(Arg *A); arglist_type &getArgs() { return Args; } @@ -153,16 +154,16 @@ namespace driver { /// @name Arg Removal /// @{ - /// eraseArg - Remove any option matching \arg Id. + /// eraseArg - Remove any option matching \p Id. void eraseArg(OptSpecifier Id); /// @} /// @name Arg Access /// @{ - /// hasArg - Does the arg list contain any option matching \arg Id. + /// hasArg - Does the arg list contain any option matching \p Id. /// - /// \arg Claim Whether the argument should be claimed, if it exists. + /// \p Claim Whether the argument should be claimed, if it exists. bool hasArgNoClaim(OptSpecifier Id) const { return getLastArgNoClaim(Id) != 0; } @@ -176,9 +177,9 @@ namespace driver { return getLastArg(Id0, Id1, Id2) != 0; } - /// getLastArg - Return the last argument matching \arg Id, or null. + /// getLastArg - Return the last argument matching \p Id, or null. /// - /// \arg Claim Whether the argument should be claimed, if it exists. + /// \p Claim Whether the argument should be claimed, if it exists. Arg *getLastArgNoClaim(OptSpecifier Id) const; Arg *getLastArg(OptSpecifier Id) const; Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const; @@ -196,7 +197,7 @@ namespace driver { OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5, OptSpecifier Id6, OptSpecifier Id7) const; - /// getArgString - Return the input argument string at \arg Index. + /// getArgString - Return the input argument string at \p Index. virtual const char *getArgString(unsigned Index) const = 0; /// getNumInputArgStrings - Return the number of original argument strings, @@ -233,15 +234,13 @@ namespace driver { /// @name Translation Utilities /// @{ - /// hasFlag - Given an option \arg Pos and its negative form \arg - /// Neg, return true if the option is present, false if the - /// negation is present, and \arg Default if neither option is - /// given. If both the option and its negation are present, the - /// last one wins. + /// hasFlag - Given an option \p Pos and its negative form \p Neg, return + /// true if the option is present, false if the negation is present, and + /// \p Default if neither option is given. If both the option and its + /// negation are present, the last one wins. bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const; - /// AddLastArg - Render only the last argument match \arg Id0, if - /// present. + /// AddLastArg - Render only the last argument match \p Id0, if present. void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; /// AddAllArgs - Render all arguments matching the given ids. @@ -286,8 +285,8 @@ namespace driver { } 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. + /// \brief Create an arg string for (\p LHS + \p RHS), reusing the + /// string at \p Index if possible. const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS, StringRef RHS) const; @@ -347,7 +346,7 @@ namespace driver { mutable arglist_type SynthesizedArgs; public: - /// Construct a new derived arg list from \arg BaseArgs. + /// Construct a new derived arg list from \p BaseArgs. DerivedArgList(const InputArgList &BaseArgs); ~DerivedArgList(); @@ -374,55 +373,54 @@ namespace driver { virtual const char *MakeArgString(StringRef Str) const; - /// AddFlagArg - Construct a new FlagArg for the given option \arg Id and + /// AddFlagArg - Construct a new FlagArg for the given option \p Id and /// append it to the argument list. - void AddFlagArg(const Arg *BaseArg, const Option *Opt) { + void AddFlagArg(const Arg *BaseArg, const Option Opt) { append(MakeFlagArg(BaseArg, Opt)); } /// AddPositionalArg - Construct a new Positional arg for the given option - /// \arg Id, with the provided \arg Value and append it to the argument + /// \p Id, with the provided \p Value and append it to the argument /// list. - void AddPositionalArg(const Arg *BaseArg, const Option *Opt, + void AddPositionalArg(const Arg *BaseArg, const Option Opt, StringRef Value) { append(MakePositionalArg(BaseArg, Opt, Value)); } /// AddSeparateArg - Construct a new Positional arg for the given option - /// \arg Id, with the provided \arg Value and append it to the argument + /// \p Id, with the provided \p Value and append it to the argument /// list. - void AddSeparateArg(const Arg *BaseArg, const Option *Opt, + void AddSeparateArg(const Arg *BaseArg, const Option Opt, StringRef Value) { append(MakeSeparateArg(BaseArg, Opt, Value)); } - /// 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, + /// AddJoinedArg - Construct a new Positional arg for the given option + /// \p Id, with the provided \p Value and append it to the argument list. + void AddJoinedArg(const Arg *BaseArg, const Option Opt, StringRef Value) { append(MakeJoinedArg(BaseArg, Opt, Value)); } - /// MakeFlagArg - Construct a new FlagArg for the given option - /// \arg Id. - Arg *MakeFlagArg(const Arg *BaseArg, const Option *Opt) const; + /// MakeFlagArg - Construct a new FlagArg for the given option \p Id. + Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const; /// 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, + /// given option \p Id, with the provided \p Value. + Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt, 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, + /// given option \p Id, with the provided \p Value. + Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt, 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, + /// given option \p Id, with the provided \p Value. + Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt, StringRef Value) const; /// @} diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h index 0508213..420a101 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h @@ -17,11 +17,13 @@ namespace driver { namespace cc1asoptions { enum ID { OPT_INVALID = 0, // This is not an option ID. -#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ +#define PREFIX(NAME, VALUE) +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ HELPTEXT, METAVAR) OPT_##ID, #include "clang/Driver/CC1AsOptions.inc" LastOption #undef OPTION +#undef PREFIX }; } diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td index 37ba602..9fd855a 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td @@ -18,22 +18,22 @@ include "OptParser.td" // Target Options //===----------------------------------------------------------------------===// -def triple : Separate<"-triple">, +def triple : Separate<["-"], "triple">, HelpText<"Specify target triple (e.g. x86_64-pc-linux-gnu)">; -def target_cpu : Separate<"-target-cpu">, +def target_cpu : Separate<["-"], "target-cpu">, HelpText<"Target a specific cpu type">; -def target_feature : Separate<"-target-feature">, +def target_feature : Separate<["-"], "target-feature">, HelpText<"Target specific attributes">; //===----------------------------------------------------------------------===// // Language Options //===----------------------------------------------------------------------===// -def I : JoinedOrSeparate<"-I">, MetaVarName<"<directory>">, +def I : JoinedOrSeparate<["-"], "I">, MetaVarName<"<directory>">, HelpText<"Add directory to include search path">; -def n : Flag<"-n">, +def n : Flag<["-"], "n">, HelpText<"Don't automatically start assembly file with a text section">; -def L : Flag<"-L">, +def L : Flag<["-"], "L">, HelpText<"Save temporary labels in the symbol table. " "Note this may change .s semantics, it should almost never be used " "on compiler generated code!">; @@ -42,50 +42,49 @@ def L : Flag<"-L">, // Frontend Options //===----------------------------------------------------------------------===// -def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">; +def o : Separate<["-"], "o">, MetaVarName<"<path>">, + HelpText<"Specify output file">; -def filetype : Separate<"-filetype">, +def filetype : Separate<["-"], "filetype">, HelpText<"Specify the output file type ('asm', 'null', or 'obj')">; -def help : Flag<"-help">, +def help : Flag<["-", "--"], "help">, HelpText<"Print this help text">; -def _help : Flag<"--help">, Alias<help>; -def version : Flag<"-version">, +def version : Flag<["-", "--"], "version">, HelpText<"Print the assembler version">; -def _version : Flag<"--version">, Alias<version>; -def v : Flag<"-v">, Alias<version>; +def v : Flag<["-"], "v">, Alias<version>; // Generic forwarding to LLVM options. This should only be used for debugging // and experimental features. -def mllvm : Separate<"-mllvm">, +def mllvm : Separate<["-"], "mllvm">, HelpText<"Additional arguments to forward to LLVM's option processing">; //===----------------------------------------------------------------------===// // Transliterate Options //===----------------------------------------------------------------------===// -def output_asm_variant : Separate<"-output-asm-variant">, +def output_asm_variant : Separate<["-"], "output-asm-variant">, HelpText<"Select the asm variant index to use for output">; -def show_encoding : Flag<"-show-encoding">, +def show_encoding : Flag<["-"], "show-encoding">, HelpText<"Show instruction encoding information in transliterate mode">; -def show_inst : Flag<"-show-inst">, +def show_inst : Flag<["-"], "show-inst">, HelpText<"Show internal instruction representation in transliterate mode">; //===----------------------------------------------------------------------===// // Assemble Options //===----------------------------------------------------------------------===// -def relax_all : Flag<"-relax-all">, +def relax_all : Flag<["-"], "relax-all">, HelpText<"Relax all fixups (for performance testing)">; -def no_exec_stack : Flag<"--noexecstack">, +def no_exec_stack : Flag<["--"], "noexecstack">, HelpText<"Mark the file as not needing an executable stack">; -def fatal_warnings : Flag<"--fatal-warnings">, +def fatal_warnings : Flag<["--"], "fatal-warnings">, HelpText<"Consider warnings as errors">; -def g : Flag<"-g">, HelpText<"Generate source level debug information">; +def g : Flag<["-"], "g">, HelpText<"Generate source level debug information">; -def dwarf_debug_flags : Separate<"-dwarf-debug-flags">, +def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, HelpText<"The string to embed in the Dwarf debug flags record.">; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td index 6e4d7f2..3ff2549 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td @@ -11,235 +11,238 @@ // //===----------------------------------------------------------------------===// -let Flags = [CC1Option] in { +let Flags = [CC1Option, NoDriverOption] in { //===----------------------------------------------------------------------===// // Target Options //===----------------------------------------------------------------------===// -def cxx_abi : Separate<"-cxx-abi">, +def cxx_abi : Separate<["-"], "cxx-abi">, HelpText<"Target a particular C++ ABI type">; -def target_abi : Separate<"-target-abi">, +def target_abi : Separate<["-"], "target-abi">, HelpText<"Target a particular ABI type">; -def target_cpu : Separate<"-target-cpu">, +def target_cpu : Separate<["-"], "target-cpu">, HelpText<"Target a specific cpu type">; -def target_feature : Separate<"-target-feature">, +def target_feature : Separate<["-"], "target-feature">, HelpText<"Target specific attributes">; -def target_linker_version : Separate<"-target-linker-version">, +def target_linker_version : Separate<["-"], "target-linker-version">, HelpText<"Target linker version">; -def triple : Separate<"-triple">, +def triple : Separate<["-"], "triple">, HelpText<"Specify target triple (e.g. i686-apple-darwin9)">; -def triple_EQ : Joined<"-triple=">, Alias<triple>; +def triple_EQ : Joined<["-"], "triple=">, Alias<triple>; //===----------------------------------------------------------------------===// // Analyzer Options //===----------------------------------------------------------------------===// -def analysis_UnoptimizedCFG : Flag<"-unoptimized-cfg">, +def analysis_UnoptimizedCFG : Flag<["-"], "unoptimized-cfg">, HelpText<"Generate unoptimized CFGs for all analyses">; -def analysis_CFGAddImplicitDtors : Flag<"-cfg-add-implicit-dtors">, +def analysis_CFGAddImplicitDtors : Flag<["-"], "cfg-add-implicit-dtors">, HelpText<"Add C++ implicit destructors to CFGs for all analyses">; -def analyzer_store : Separate<"-analyzer-store">, +def analyzer_store : Separate<["-"], "analyzer-store">, HelpText<"Source Code Analysis - Abstract Memory Store Models">; -def analyzer_store_EQ : Joined<"-analyzer-store=">, Alias<analyzer_store>; +def analyzer_store_EQ : Joined<["-"], "analyzer-store=">, Alias<analyzer_store>; -def analyzer_constraints : Separate<"-analyzer-constraints">, +def analyzer_constraints : Separate<["-"], "analyzer-constraints">, HelpText<"Source Code Analysis - Symbolic Constraint Engines">; -def analyzer_constraints_EQ : Joined<"-analyzer-constraints=">, +def analyzer_constraints_EQ : Joined<["-"], "analyzer-constraints=">, Alias<analyzer_constraints>; -def analyzer_output : Separate<"-analyzer-output">, +def analyzer_output : Separate<["-"], "analyzer-output">, HelpText<"Source Code Analysis - Output Options">; -def analyzer_output_EQ : Joined<"-analyzer-output=">, +def analyzer_output_EQ : Joined<["-"], "analyzer-output=">, Alias<analyzer_output>; -def analyzer_purge : Separate<"-analyzer-purge">, +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_purge_EQ : Joined<["-"], "analyzer-purge=">, Alias<analyzer_purge>; -def analyzer_opt_analyze_headers : Flag<"-analyzer-opt-analyze-headers">, +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">, +def analyzer_opt_analyze_nested_blocks : Flag<["-"], "analyzer-opt-analyze-nested-blocks">, HelpText<"Analyze the definitions of blocks in addition to functions">; -def analyzer_display_progress : Flag<"-analyzer-display-progress">, +def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">, HelpText<"Emit verbose output about the analyzer's progress">; -def analyze_function : Separate<"-analyze-function">, +def analyze_function : Separate<["-"], "analyze-function">, HelpText<"Run analysis on specific function">; -def analyze_function_EQ : Joined<"-analyze-function=">, Alias<analyze_function>; -def analyzer_eagerly_assume : Flag<"-analyzer-eagerly-assume">, +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_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">, +def trim_egraph : Flag<["-"], "trim-egraph">, HelpText<"Only show error-related paths in the analysis graph">; -def analyzer_viz_egraph_graphviz : Flag<"-analyzer-viz-egraph-graphviz">, +def analyzer_viz_egraph_graphviz : Flag<["-"], "analyzer-viz-egraph-graphviz">, HelpText<"Display exploded graph using GraphViz">; -def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">, +def analyzer_viz_egraph_ubigraph : Flag<["-"], "analyzer-viz-egraph-ubigraph">, HelpText<"Display exploded graph using Ubigraph">; -def analyzer_inline_max_stack_depth : Separate<"-analyzer-inline-max-stack-depth">, +def analyzer_inline_max_stack_depth : Separate<["-"], "analyzer-inline-max-stack-depth">, HelpText<"Bound on stack depth while inlining (4 by default)">; -def analyzer_inline_max_stack_depth_EQ : Joined<"-analyzer-inline-max-stack-depth=">, +def analyzer_inline_max_stack_depth_EQ : Joined<["-"], "analyzer-inline-max-stack-depth=">, Alias<analyzer_inline_max_stack_depth>; -def analyzer_inline_max_function_size : Separate<"-analyzer-inline-max-function-size">, +def analyzer_inline_max_function_size : Separate<["-"], "analyzer-inline-max-function-size">, HelpText<"Bound on the number of basic blocks in an inlined function (200 by default)">; -def analyzer_inline_max_function_size_EQ : Joined<"-analyzer-inline-max-function-size=">, +def analyzer_inline_max_function_size_EQ : Joined<["-"], "analyzer-inline-max-function-size=">, Alias<analyzer_inline_max_function_size>; -def analyzer_ipa : Separate<"-analyzer-ipa">, +def analyzer_ipa : Separate<["-"], "analyzer-ipa">, HelpText<"Specify the inter-procedural analysis mode">; -def analyzer_ipa_EQ : Joined<"-analyzer-ipa=">, Alias<analyzer_ipa>; +def analyzer_ipa_EQ : Joined<["-"], "analyzer-ipa=">, Alias<analyzer_ipa>; -def analyzer_inlining_mode : Separate<"-analyzer-inlining-mode">, +def analyzer_inlining_mode : Separate<["-"], "analyzer-inlining-mode">, HelpText<"Specify the function selection heuristic used during inlining">; -def analyzer_inlining_mode_EQ : Joined<"-analyzer-inlining-mode=">, Alias<analyzer_inlining_mode>; +def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias<analyzer_inlining_mode>; -def analyzer_disable_retry_exhausted : Flag<"-analyzer-disable-retry-exhausted">, +def analyzer_disable_retry_exhausted : Flag<["-"], "analyzer-disable-retry-exhausted">, HelpText<"Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)">; -def analyzer_max_nodes : Separate<"-analyzer-max-nodes">, +def analyzer_max_nodes : Separate<["-"], "analyzer-max-nodes">, HelpText<"The maximum number of nodes the analyzer can generate (150000 default, 0 = no limit)">; -def analyzer_max_loop : Separate<"-analyzer-max-loop">, +def analyzer_max_loop : Separate<["-"], "analyzer-max-loop">, HelpText<"The maximum number of times the analyzer will go through a loop">; -def analyzer_stats : Flag<"-analyzer-stats">, +def analyzer_stats : Flag<["-"], "analyzer-stats">, HelpText<"Print internal analyzer statistics.">; -def analyzer_checker : Separate<"-analyzer-checker">, +def analyzer_checker : Separate<["-"], "analyzer-checker">, HelpText<"Choose analyzer checkers to enable">; -def analyzer_checker_EQ : Joined<"-analyzer-checker=">, +def analyzer_checker_EQ : Joined<["-"], "analyzer-checker=">, Alias<analyzer_checker>; -def analyzer_disable_checker : Separate<"-analyzer-disable-checker">, +def analyzer_disable_checker : Separate<["-"], "analyzer-disable-checker">, HelpText<"Choose analyzer checkers to disable">; -def analyzer_disable_checker_EQ : Joined<"-analyzer-disable-checker=">, +def analyzer_disable_checker_EQ : Joined<["-"], "analyzer-disable-checker=">, Alias<analyzer_disable_checker>; -def analyzer_checker_help : Flag<"-analyzer-checker-help">, +def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">, HelpText<"Display the list of analyzer checkers that are available">; +def analyzer_config : Separate<["-"], "analyzer-config">, + HelpText<"Choose analyzer options to enable">; + //===----------------------------------------------------------------------===// // Migrator Options //===----------------------------------------------------------------------===// -def migrator_no_nsalloc_error : Flag<"-no-ns-alloc-error">, +def migrator_no_nsalloc_error : Flag<["-"], "no-ns-alloc-error">, HelpText<"Do not error on use of NSAllocateCollectable/NSReallocateCollectable">; -def migrator_no_finalize_removal : Flag<"-no-finalize-removal">, +def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">, HelpText<"Do not remove finalize method in gc mode">; //===----------------------------------------------------------------------===// // CodeGen Options //===----------------------------------------------------------------------===// -def disable_llvm_optzns : Flag<"-disable-llvm-optzns">, +def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">, HelpText<"Don't run LLVM optimization passes">; -def disable_llvm_verifier : Flag<"-disable-llvm-verifier">, +def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">, HelpText<"Don't run the LLVM IR verifier pass">; -def disable_red_zone : Flag<"-disable-red-zone">, +def disable_red_zone : Flag<["-"], "disable-red-zone">, HelpText<"Do not emit code that uses the red zone.">; -def fdebug_compilation_dir : Separate<"-fdebug-compilation-dir">, +def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">, HelpText<"The compilation directory to embed in the debug info.">; -def dwarf_debug_flags : Separate<"-dwarf-debug-flags">, +def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, HelpText<"The string to embed in the Dwarf debug flags record.">; -def fforbid_guard_variables : Flag<"-fforbid-guard-variables">, +def dwarf_column_info : Flag<["-"], "dwarf-column-info">, + HelpText<"Turn on column location information.">; +def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">, HelpText<"Emit an error if a C++ static local initializer would need a guard variable">; -def no_implicit_float : Flag<"-no-implicit-float">, +def no_implicit_float : Flag<["-"], "no-implicit-float">, HelpText<"Don't generate implicit floating point instructions">; -def fdump_vtable_layouts : Flag<"-fdump-vtable-layouts">, +def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">, HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">; -def femit_coverage_notes : Flag<"-femit-coverage-notes">, +def femit_coverage_notes : Flag<["-"], "femit-coverage-notes">, HelpText<"Emit a gcov coverage notes file when compiling.">; -def femit_coverage_data: Flag<"-femit-coverage-data">, +def femit_coverage_data: Flag<["-"], "femit-coverage-data">, HelpText<"Instrument the program to emit gcov coverage data when run.">; -def coverage_file : Separate<"-coverage-file">, +def coverage_file : Separate<["-"], "coverage-file">, HelpText<"Emit coverage data to this filename. The extension will be replaced.">; -def coverage_file_EQ : Joined<"-coverage-file=">, Alias<coverage_file>; -def fuse_register_sized_bitfield_access: Flag<"-fuse-register-sized-bitfield-access">, +def coverage_file_EQ : Joined<["-"], "coverage-file=">, Alias<coverage_file>; +def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfield-access">, HelpText<"Use register sized accesses to bit-fields, when possible.">; -def relaxed_aliasing : Flag<"-relaxed-aliasing">, +def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, HelpText<"Turn off Type Based Alias Analysis">; -def masm_verbose : Flag<"-masm-verbose">, +def masm_verbose : Flag<["-"], "masm-verbose">, HelpText<"Generate verbose assembly output">; -def mcode_model : Separate<"-mcode-model">, +def mcode_model : Separate<["-"], "mcode-model">, HelpText<"The code model to use">; -def mdebug_pass : Separate<"-mdebug-pass">, +def mdebug_pass : Separate<["-"], "mdebug-pass">, HelpText<"Enable additional debug output">; -def mdisable_fp_elim : Flag<"-mdisable-fp-elim">, +def mdisable_fp_elim : Flag<["-"], "mdisable-fp-elim">, HelpText<"Disable frame pointer elimination optimization">; -def mdisable_tail_calls : Flag<"-mdisable-tail-calls">, +def mdisable_tail_calls : Flag<["-"], "mdisable-tail-calls">, HelpText<"Disable tail call optimization, keeping the call stack accurate">; -def menable_no_infinities : Flag<"-menable-no-infs">, +def menable_no_infinities : Flag<["-"], "menable-no-infs">, HelpText<"Allow optimization to assume there are no infinities.">; -def menable_no_nans : Flag<"-menable-no-nans">, +def menable_no_nans : Flag<["-"], "menable-no-nans">, HelpText<"Allow optimization to assume there are no NaNs.">; -def menable_unsafe_fp_math : Flag<"-menable-unsafe-fp-math">, +def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">, HelpText<"Allow unsafe floating-point math optimizations which may decrease " "precision">; -def mfloat_abi : Separate<"-mfloat-abi">, +def mfloat_abi : Separate<["-"], "mfloat-abi">, HelpText<"The float ABI to use">; -def mlimit_float_precision : Separate<"-mlimit-float-precision">, +def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">, HelpText<"Limit float precision to the given value">; -def mno_exec_stack : Flag<"-mnoexecstack">, +def mno_exec_stack : Flag<["-"], "mnoexecstack">, HelpText<"Mark the file as not needing an executable stack">; -def mno_zero_initialized_in_bss : Flag<"-mno-zero-initialized-in-bss">, +def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">, HelpText<"Do not put zero initialized data in the BSS">; -def backend_option : Separate<"-backend-option">, +def backend_option : Separate<["-"], "backend-option">, HelpText<"Additional arguments to forward to LLVM backend (during code gen)">; -def mregparm : Separate<"-mregparm">, +def mregparm : Separate<["-"], "mregparm">, HelpText<"Limit the number of registers available for integer arguments">; -def msave_temp_labels : Flag<"-msave-temp-labels">, +def msave_temp_labels : Flag<["-"], "msave-temp-labels">, HelpText<"(integrated-as) Save temporary labels">; -def mrelocation_model : Separate<"-mrelocation-model">, +def mrelocation_model : Separate<["-"], "mrelocation-model">, HelpText<"The relocation model to use">; -def munwind_tables : Flag<"-munwind-tables">, +def munwind_tables : Flag<["-"], "munwind-tables">, HelpText<"Generate unwinding tables for all functions">; -def fuse_init_array : Flag<"-fuse-init-array">, +def fuse_init_array : Flag<["-"], "fuse-init-array">, HelpText<"Use .init_array instead of .ctors">; -def mconstructor_aliases : Flag<"-mconstructor-aliases">, +def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">, HelpText<"Emit complete constructors and destructors as aliases when possible">; -def mlink_bitcode_file : Separate<"-mlink-bitcode-file">, +def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">, HelpText<"Link the given bitcode file before performing optimizations.">; //===----------------------------------------------------------------------===// // Dependency Output Options //===----------------------------------------------------------------------===// -def sys_header_deps : Flag<"-sys-header-deps">, +def sys_header_deps : Flag<["-"], "sys-header-deps">, HelpText<"Include system headers in dependency output">; -def header_include_file : Separate<"-header-include-file">, +def header_include_file : Separate<["-"], "header-include-file">, HelpText<"Filename (or -) to write header include output to">; //===----------------------------------------------------------------------===// // Diagnostic Options //===----------------------------------------------------------------------===// -def dump_build_information : Separate<"-dump-build-information">, +def dump_build_information : Separate<["-"], "dump-build-information">, MetaVarName<"<filename>">, HelpText<"output a dump of some build information to a file">; -def diagnostic_log_file : Separate<"-diagnostic-log-file">, +def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">, HelpText<"Filename (or -) to log diagnostics to">; -def diagnostic_serialized_file : Separate<"-serialize-diagnostic-file">, +def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">, MetaVarName<"<filename>">, HelpText<"File for serializing diagnostics in a binary format">; -def fdiagnostics_format : Separate<"-fdiagnostics-format">, +def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">, HelpText<"Change diagnostic formatting to match IDE and command line tools">; -def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">, +def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">, HelpText<"Print diagnostic category">; -def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">, +def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"<N>">, HelpText<"Set the tab stop distance.">; -def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">, +def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"<N>">, HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">; -def fmacro_backtrace_limit : Separate<"-fmacro-backtrace-limit">, MetaVarName<"<N>">, +def fmacro_backtrace_limit : Separate<["-"], "fmacro-backtrace-limit">, MetaVarName<"<N>">, HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">; -def ftemplate_backtrace_limit : Separate<"-ftemplate-backtrace-limit">, MetaVarName<"<N>">, +def ftemplate_backtrace_limit : Separate<["-"], "ftemplate-backtrace-limit">, MetaVarName<"<N>">, HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">; -def fconstexpr_backtrace_limit : Separate<"-fconstexpr-backtrace-limit">, MetaVarName<"<N>">, +def fconstexpr_backtrace_limit : Separate<["-"], "fconstexpr-backtrace-limit">, MetaVarName<"<N>">, HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">; -def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">, +def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"<N>">, HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">; -def Wno_rewrite_macros : Flag<"-Wno-rewrite-macros">, +def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">, HelpText<"Silence ObjC rewriting warnings">; //===----------------------------------------------------------------------===// @@ -248,43 +251,43 @@ def Wno_rewrite_macros : Flag<"-Wno-rewrite-macros">, // This isn't normally used, it is just here so we can parse a // CompilerInvocation out of a driver-derived argument vector. -def cc1 : Flag<"-cc1">; +def cc1 : Flag<["-"], "cc1">; -def ast_merge : Separate<"-ast-merge">, +def ast_merge : Separate<["-"], "ast-merge">, MetaVarName<"<ast file>">, HelpText<"Merge the given AST file into the translation unit being compiled.">; -def code_completion_at : Separate<"-code-completion-at">, +def code_completion_at : Separate<["-"], "code-completion-at">, MetaVarName<"<file>:<line>:<column>">, HelpText<"Dump code-completion information at a location">; -def remap_file : Separate<"-remap-file">, +def remap_file : Separate<["-"], "remap-file">, MetaVarName<"<from>;<to>">, HelpText<"Replace the contents of the <from> file with the contents of the <to> file">; -def code_completion_at_EQ : Joined<"-code-completion-at=">, +def code_completion_at_EQ : Joined<["-"], "code-completion-at=">, Alias<code_completion_at>; -def code_completion_macros : Flag<"-code-completion-macros">, +def code_completion_macros : Flag<["-"], "code-completion-macros">, HelpText<"Include macros in code-completion results">; -def code_completion_patterns : Flag<"-code-completion-patterns">, +def code_completion_patterns : Flag<["-"], "code-completion-patterns">, HelpText<"Include code patterns in code-completion results">; -def no_code_completion_globals : Flag<"-no-code-completion-globals">, +def no_code_completion_globals : Flag<["-"], "no-code-completion-globals">, HelpText<"Do not include global declarations in code-completion results.">; -def code_completion_brief_comments : Flag<"-code-completion-brief-comments">, +def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments">, HelpText<"Include brief documentation comments in code-completion results.">; -def disable_free : Flag<"-disable-free">, +def disable_free : Flag<["-"], "disable-free">, HelpText<"Disable freeing of memory on exit">; -def load : Separate<"-load">, MetaVarName<"<dsopath>">, +def load : Separate<["-"], "load">, MetaVarName<"<dsopath>">, HelpText<"Load the named plugin (dynamic shared object)">; -def plugin : Separate<"-plugin">, MetaVarName<"<name>">, +def plugin : Separate<["-"], "plugin">, MetaVarName<"<name>">, HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">; -def plugin_arg : JoinedAndSeparate<"-plugin-arg-">, +def plugin_arg : JoinedAndSeparate<["-"], "plugin-arg-">, MetaVarName<"<name> <arg>">, HelpText<"Pass <arg> to plugin <name>">; -def add_plugin : Separate<"-add-plugin">, MetaVarName<"<name>">, +def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"<name>">, HelpText<"Use the named plugin action in addition to the default action">; -def resource_dir : Separate<"-resource-dir">, +def resource_dir : Separate<["-"], "resource-dir">, HelpText<"The directory which holds the compiler resource files">; -def version : Flag<"-version">, +def version : Flag<["-"], "version">, HelpText<"Print the compiler version">; -def ast_dump_filter : Separate<"-ast-dump-filter">, +def ast_dump_filter : Separate<["-"], "ast-dump-filter">, MetaVarName<"<dump_filter>">, HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration" " nodes having a certain substring in a qualified name. Use" @@ -292,191 +295,197 @@ def ast_dump_filter : Separate<"-ast-dump-filter">, let Group = Action_Group in { -def Eonly : Flag<"-Eonly">, +def Eonly : Flag<["-"], "Eonly">, HelpText<"Just run preprocessor, no output (for timings)">; -def dump_raw_tokens : Flag<"-dump-raw-tokens">, +def dump_raw_tokens : Flag<["-"], "dump-raw-tokens">, HelpText<"Lex file in raw mode and dump raw tokens">; -def analyze : Flag<"-analyze">, +def analyze : Flag<["-"], "analyze">, HelpText<"Run static analysis engine">; -def dump_tokens : Flag<"-dump-tokens">, +def dump_tokens : Flag<["-"], "dump-tokens">, HelpText<"Run preprocessor, dump internal rep of tokens">; -def init_only : Flag<"-init-only">, +def init_only : Flag<["-"], "init-only">, HelpText<"Only execute frontend initialization">; -def fixit : Flag<"-fixit">, +def fixit : Flag<["-"], "fixit">, HelpText<"Apply fix-it advice to the input source">; -def fixit_EQ : Joined<"-fixit=">, +def fixit_EQ : Joined<["-"], "fixit=">, HelpText<"Apply fix-it advice creating a file with the given suffix">; -def print_preamble : Flag<"-print-preamble">, +def print_preamble : Flag<["-"], "print-preamble">, HelpText<"Print the \"preamble\" of a file, which is a candidate for implicit" " precompiled headers.">; -def emit_html : Flag<"-emit-html">, +def emit_html : Flag<["-"], "emit-html">, HelpText<"Output input source as HTML">; -def ast_print : Flag<"-ast-print">, +def ast_print : Flag<["-"], "ast-print">, HelpText<"Build ASTs and then pretty-print them">; -def ast_list : Flag<"-ast-list">, +def ast_list : Flag<["-"], "ast-list">, HelpText<"Build ASTs and print the list of declaration node qualified names">; -def ast_dump : Flag<"-ast-dump">, +def ast_dump : Flag<["-"], "ast-dump">, HelpText<"Build ASTs and then debug dump them">; -def ast_dump_xml : Flag<"-ast-dump-xml">, +def ast_dump_xml : Flag<["-"], "ast-dump-xml">, HelpText<"Build ASTs and then debug dump them in a verbose XML format">; -def ast_view : Flag<"-ast-view">, +def ast_view : Flag<["-"], "ast-view">, HelpText<"Build ASTs and view them with GraphViz">; -def print_decl_contexts : Flag<"-print-decl-contexts">, +def print_decl_contexts : Flag<["-"], "print-decl-contexts">, HelpText<"Print DeclContexts and their Decls">; -def emit_module : Flag<"-emit-module">, +def emit_module : Flag<["-"], "emit-module">, HelpText<"Generate pre-compiled module file from a module map">; -def emit_pth : Flag<"-emit-pth">, +def emit_pth : Flag<["-"], "emit-pth">, HelpText<"Generate pre-tokenized header file">; -def emit_pch : Flag<"-emit-pch">, +def emit_pch : Flag<["-"], "emit-pch">, HelpText<"Generate pre-compiled header file">; -def emit_llvm_bc : Flag<"-emit-llvm-bc">, +def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">, HelpText<"Build ASTs then convert to LLVM, emit .bc file">; -def emit_llvm_only : Flag<"-emit-llvm-only">, +def emit_llvm_only : Flag<["-"], "emit-llvm-only">, HelpText<"Build ASTs and convert to LLVM, discarding output">; -def emit_codegen_only : Flag<"-emit-codegen-only">, +def emit_codegen_only : Flag<["-"], "emit-codegen-only">, HelpText<"Generate machine code, but discard output">; -def emit_obj : Flag<"-emit-obj">, +def emit_obj : Flag<["-"], "emit-obj">, HelpText<"Emit native object files">; -def rewrite_test : Flag<"-rewrite-test">, +def rewrite_test : Flag<["-"], "rewrite-test">, HelpText<"Rewriter playground">; -def rewrite_macros : Flag<"-rewrite-macros">, +def rewrite_macros : Flag<["-"], "rewrite-macros">, HelpText<"Expand macros without full preprocessing">; -def migrate : Flag<"-migrate">, +def migrate : Flag<["-"], "migrate">, HelpText<"Migrate source code">; } -def mt_migrate_directory : Separate<"-mt-migrate-directory">, +def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">, HelpText<"Directory for temporary files produced during ARC or ObjC migration">; -def arcmt_check : Flag<"-arcmt-check">, +def arcmt_check : Flag<["-"], "arcmt-check">, HelpText<"Check for ARC migration issues that need manual handling">; -def arcmt_modify : Flag<"-arcmt-modify">, +def arcmt_modify : Flag<["-"], "arcmt-modify">, HelpText<"Apply modifications to files to conform to ARC">; -def arcmt_migrate : Flag<"-arcmt-migrate">, +def arcmt_migrate : Flag<["-"], "arcmt-migrate">, HelpText<"Apply modifications and produces temporary files that conform to ARC">; -def relocatable_pch : Flag<"-relocatable-pch">, +def relocatable_pch : Flag<["-", "--"], "relocatable-pch">, HelpText<"Whether to build a relocatable precompiled header">; -def print_stats : Flag<"-print-stats">, +def print_stats : Flag<["-"], "print-stats">, HelpText<"Print performance metrics and statistics">; -def fdump_record_layouts : Flag<"-fdump-record-layouts">, +def fdump_record_layouts : Flag<["-"], "fdump-record-layouts">, HelpText<"Dump record layout information">; -def fdump_record_layouts_simple : Flag<"-fdump-record-layouts-simple">, +def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">, HelpText<"Dump record layout information in a simple form used for testing">; -def fix_what_you_can : Flag<"-fix-what-you-can">, +def fix_what_you_can : Flag<["-"], "fix-what-you-can">, HelpText<"Apply fix-it advice even in the presence of unfixable errors">; -def fix_only_warnings : Flag<"-fix-only-warnings">, +def fix_only_warnings : Flag<["-"], "fix-only-warnings">, HelpText<"Apply fix-it advice only for warnings, not errors">; -def fixit_recompile : Flag<"-fixit-recompile">, +def fixit_recompile : Flag<["-"], "fixit-recompile">, HelpText<"Apply fix-it changes and recompile">; -def fixit_to_temp : Flag<"-fixit-to-temporary">, +def fixit_to_temp : Flag<["-"], "fixit-to-temporary">, HelpText<"Apply fix-it changes to temporary files">; -def foverride_record_layout_EQ : Joined<"-foverride-record-layout=">, +def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">, HelpText<"Override record layouts with those in the given file">; //===----------------------------------------------------------------------===// // Language Options //===----------------------------------------------------------------------===// -def fblocks_runtime_optional : Flag<"-fblocks-runtime-optional">, +def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, HelpText<"Weakly link in the blocks runtime">; -def fsjlj_exceptions : Flag<"-fsjlj-exceptions">, +def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, HelpText<"Use SjLj style exceptions">; -def fhidden_weak_vtables : Flag<"-fhidden-weak-vtables">, +def fhidden_weak_vtables : Flag<["-"], "fhidden-weak-vtables">, HelpText<"Generate weak vtables and RTTI with hidden visibility">; -def main_file_name : Separate<"-main-file-name">, +def main_file_name : Separate<["-"], "main-file-name">, HelpText<"Main file name to use for debug info">; -def fno_signed_char : Flag<"-fno-signed-char">, +def fno_signed_char : Flag<["-"], "fno-signed-char">, HelpText<"Char is unsigned">; -def fconstant_string_class : Separate<"-fconstant-string-class">, +def fno_wchar : Flag<["-"], "fno-wchar">, + HelpText<"Disable C++ builtin type wchar_t">; +def fconstant_string_class : Separate<["-"], "fconstant-string-class">, MetaVarName<"<class name>">, HelpText<"Specify the class to use for constant Objective-C string objects.">; -def fobjc_arc_cxxlib_EQ : Joined<"-fobjc-arc-cxxlib=">, +def fobjc_arc_cxxlib_EQ : Joined<["-"], "fobjc-arc-cxxlib=">, HelpText<"Objective-C++ Automatic Reference Counting standard library kind">; -def fobjc_runtime_has_weak : Flag<"-fobjc-runtime-has-weak">, +def fobjc_runtime_has_weak : Flag<["-"], "fobjc-runtime-has-weak">, HelpText<"The target Objective-C runtime supports ARC weak operations">; -def fobjc_dispatch_method_EQ : Joined<"-fobjc-dispatch-method=">, +def fobjc_dispatch_method_EQ : Joined<["-"], "fobjc-dispatch-method=">, HelpText<"Objective-C dispatch method to use">; -def fobjc_default_synthesize_properties : Flag<"-fobjc-default-synthesize-properties">, +def fobjc_default_synthesize_properties : Flag<["-"], "fobjc-default-synthesize-properties">, HelpText<"enable the default synthesis of Objective-C properties">; -def pic_level : Separate<"-pic-level">, +def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">, + HelpText<"enable extended encoding of block type signature">; +def pic_level : Separate<["-"], "pic-level">, HelpText<"Value for __PIC__">; -def pie_level : Separate<"-pie-level">, +def pie_level : Separate<["-"], "pie-level">, HelpText<"Value for __PIE__">; -def fno_validate_pch : Flag<"-fno-validate-pch">, +def fno_validate_pch : Flag<["-"], "fno-validate-pch">, HelpText<"Disable validation of precompiled headers">; -def dump_deserialized_pch_decls : Flag<"-dump-deserialized-decls">, +def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">, HelpText<"Dump declarations that are deserialized from PCH, for testing">; -def error_on_deserialized_pch_decl : Separate<"-error-on-deserialized-decl">, +def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">, HelpText<"Emit error if a specific declaration is deserialized from PCH, for testing">; -def error_on_deserialized_pch_decl_EQ : Joined<"-error-on-deserialized-decl=">, +def error_on_deserialized_pch_decl_EQ : Joined<["-"], "error-on-deserialized-decl=">, Alias<error_on_deserialized_pch_decl>; -def static_define : Flag<"-static-define">, +def static_define : Flag<["-"], "static-define">, HelpText<"Should __STATIC__ be defined">; -def stack_protector : Separate<"-stack-protector">, +def stack_protector : Separate<["-"], "stack-protector">, HelpText<"Enable stack protectors">; -def fvisibility : Separate<"-fvisibility">, +def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">, + HelpText<"Lower bound for a buffer to be considered for stack protection">; +def fvisibility : Separate<["-"], "fvisibility">, HelpText<"Default symbol visibility">; -def ftemplate_depth : Separate<"-ftemplate-depth">, +def ftemplate_depth : Separate<["-"], "ftemplate-depth">, HelpText<"Maximum depth of recursive template instantiation">; -def fconstexpr_depth : Separate<"-fconstexpr-depth">, +def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">, HelpText<"Maximum depth of recursive constexpr function calls">; -def fconst_strings : Flag<"-fconst-strings">, +def fconst_strings : Flag<["-"], "fconst-strings">, HelpText<"Use a const qualified type for string literals in C and ObjC">; -def fno_const_strings : Flag<"-fno-const-strings">, +def fno_const_strings : Flag<["-"], "fno-const-strings">, HelpText<"Don't use a const qualified type for string literals in C and ObjC">; -def fno_bitfield_type_align : Flag<"-fno-bitfield-type-align">, +def fno_bitfield_type_align : Flag<["-"], "fno-bitfield-type-align">, HelpText<"Ignore bit-field types when aligning structures">; -def ffake_address_space_map : Flag<"-ffake-address-space-map">, +def ffake_address_space_map : Flag<["-"], "ffake-address-space-map">, HelpText<"Use a fake address space map; OpenCL testing purposes only">; -def funknown_anytype : Flag<"-funknown-anytype">, +def funknown_anytype : Flag<["-"], "funknown-anytype">, HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">; -def fdebugger_support : Flag<"-fdebugger-support">, +def fdebugger_support : Flag<["-"], "fdebugger-support">, HelpText<"Enable special debugger support behavior">; -def fdebugger_cast_result_to_id : Flag<"-fdebugger-cast-result-to-id">, +def fdebugger_cast_result_to_id : Flag<["-"], "fdebugger-cast-result-to-id">, HelpText<"Enable casting unknown expression results to id">; -def fdebugger_objc_literal : Flag<"-fdebugger-objc-literal">, +def fdebugger_objc_literal : Flag<["-"], "fdebugger-objc-literal">, HelpText<"Enable special debugger support for Objective-C subscripting and literals">; -def fdeprecated_macro : Flag<"-fdeprecated-macro">, +def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">, HelpText<"Defines the __DEPRECATED macro">; -def fno_deprecated_macro : Flag<"-fno-deprecated-macro">, +def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">, HelpText<"Undefines the __DEPRECATED macro">; //===----------------------------------------------------------------------===// // Header Search Options //===----------------------------------------------------------------------===// -def nostdsysteminc : Flag<"-nostdsysteminc">, +def nostdsysteminc : Flag<["-"], "nostdsysteminc">, HelpText<"Disable standard system #include directories">; -def fmodule_name : Joined<"-fmodule-name=">, +def fmodule_name : Joined<["-"], "fmodule-name=">, MetaVarName<"<name>">, HelpText<"Specify the name of the module to build">; -def fdisable_module_hash : Flag<"-fdisable-module-hash">, +def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">, HelpText<"Disable the module hash">; -def c_isystem : JoinedOrSeparate<"-c-isystem">, MetaVarName<"<directory>">, +def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">, HelpText<"Add directory to the C SYSTEM include search path">; -def objc_isystem : JoinedOrSeparate<"-objc-isystem">, +def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">, MetaVarName<"<directory>">, HelpText<"Add directory to the ObjC SYSTEM include search path">; -def objcxx_isystem : JoinedOrSeparate<"-objcxx-isystem">, +def objcxx_isystem : JoinedOrSeparate<["-"], "objcxx-isystem">, MetaVarName<"<directory>">, HelpText<"Add directory to the ObjC++ SYSTEM include search path">; -def internal_isystem : JoinedOrSeparate<"-internal-isystem">, +def internal_isystem : JoinedOrSeparate<["-"], "internal-isystem">, MetaVarName<"<directory>">, HelpText<"Add directory to the internal system include search path; these " "are assumed to not be user-provided and are used to model system " "and standard headers' paths.">; -def internal_externc_isystem : JoinedOrSeparate<"-internal-externc-isystem">, +def internal_externc_isystem : JoinedOrSeparate<["-"], "internal-externc-isystem">, MetaVarName<"<directory>">, HelpText<"Add directory to the internal system include search path with " "implicit extern \"C\" semantics; these are assumed to not be " "user-provided and are used to model system and standard headers' " "paths.">; -def isystem_prefix : JoinedOrSeparate<"-isystem-prefix">, +def isystem_prefix : JoinedOrSeparate<["-"], "isystem-prefix">, MetaVarName<"<prefix>">, HelpText<"Treat all #include paths starting with <prefix> as including a " "system header.">; -def ino_system_prefix : JoinedOrSeparate<"-ino-system-prefix">, +def ino_system_prefix : JoinedOrSeparate<["-"], "ino-system-prefix">, MetaVarName<"<prefix>">, HelpText<"Treat all #include paths starting with <prefix> as not including a " "system header.">; @@ -485,42 +494,42 @@ def ino_system_prefix : JoinedOrSeparate<"-ino-system-prefix">, // Preprocessor Options //===----------------------------------------------------------------------===// -def include_pth : Separate<"-include-pth">, MetaVarName<"<file>">, +def include_pth : Separate<["-"], "include-pth">, MetaVarName<"<file>">, HelpText<"Include file before parsing">; -def chain_include : Separate<"-chain-include">, MetaVarName<"<file>">, +def chain_include : Separate<["-"], "chain-include">, MetaVarName<"<file>">, HelpText<"Include and chain a header file after turning it into PCH">; -def preamble_bytes_EQ : Joined<"-preamble-bytes=">, +def preamble_bytes_EQ : Joined<["-"], "preamble-bytes=">, HelpText<"Assume that the precompiled header is a precompiled preamble " "covering the first N bytes of the main file">; -def token_cache : Separate<"-token-cache">, MetaVarName<"<path>">, +def token_cache : Separate<["-"], "token-cache">, MetaVarName<"<path>">, HelpText<"Use specified token cache file">; -def detailed_preprocessing_record : Flag<"-detailed-preprocessing-record">, +def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">, HelpText<"include a detailed record of preprocessing actions">; //===----------------------------------------------------------------------===// // OpenCL Options //===----------------------------------------------------------------------===// -def cl_opt_disable : Flag<"-cl-opt-disable">, +def cl_opt_disable : Flag<["-"], "cl-opt-disable">, HelpText<"OpenCL only. This option disables all optimizations. The default is optimizations are enabled.">; -def cl_single_precision_constant : Flag<"-cl-single-precision-constant">, +def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">, HelpText<"OpenCL only. Treat double precision floating-point constant as single precision constant.">; -def cl_finite_math_only : Flag<"-cl-finite-math-only">, +def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">; -def cl_unsafe_math_optimizations : Flag<"-cl-unsafe-math-optimizations">, +def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">, HelpText<"OpenCL only. Allow unsafe floating-point optimizations. Also implies -cl-no-signed-zeros and -cl-mad-enable">; -def cl_fast_relaxed_math : Flag<"-cl-fast-relaxed-math">, +def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">, HelpText<"OpenCL only. Sets -cl-finite-math-only and -cl-unsafe-math-optimizations, and defines __FAST_RELAXED_MATH__">; -def cl_mad_enable : Flag<"-cl-mad-enable">, +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=">, +def cl_std_EQ : Joined<["-"], "cl-std=">, HelpText<"OpenCL language standard to compile for">; //===----------------------------------------------------------------------===// // CUDA Options //===----------------------------------------------------------------------===// -def fcuda_is_device : Flag<"-fcuda-is-device">, +def fcuda_is_device : Flag<["-"], "fcuda-is-device">, HelpText<"Generate code for CUDA device">; } // let Flags = [CC1Option] diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h index 7a10d56..5f63aa7 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h @@ -98,8 +98,7 @@ public: StringRef getSysRoot() const; /// getArgsForToolChain - Return the derived argument list for the - /// tool chain \arg TC (or the default tool chain, if TC is not - /// specified). + /// tool chain \p TC (or the default tool chain, if TC is not specified). /// /// \param BoundArch - The bound architecture name, or 0. const DerivedArgList &getArgsForToolChain(const ToolChain *TC, @@ -142,6 +141,14 @@ public: void PrintJob(raw_ostream &OS, const Job &J, const char *Terminator, bool Quote) const; + /// PrintDiagnosticJob - Print one job in -### format, but with the + /// superfluous options removed, which are not necessary for + /// reproducing the crash. + /// + /// \param OS - The stream to print on. + /// \param J - The job to print. + void PrintDiagnosticJob(raw_ostream &OS, const Job &J) const; + /// ExecuteCommand - Execute an actual command. /// /// \param FailingCommand - For non-zero results, this will be set to the diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Driver.h b/contrib/llvm/tools/clang/include/clang/Driver/Driver.h index 6095055..b752ce6 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Driver.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Driver.h @@ -146,28 +146,11 @@ private: /// jobs. unsigned CheckInputsExist : 1; - /// Use the clang compiler where possible. - unsigned CCCUseClang : 1; - - /// Use clang for handling C++ and Objective-C++ inputs. - unsigned CCCUseClangCXX : 1; - - /// Use clang as a preprocessor (clang's preprocessor will still be - /// used where an integrated CPP would). - unsigned CCCUseClangCPP : 1; - - /// \brief Force use of clang frontend. - unsigned ForcedClangUse : 1; - public: /// Use lazy precompiled headers for PCH support. unsigned CCCUsePCH : 1; private: - /// Only use clang for the given architectures (only used when - /// non-empty). - std::set<llvm::Triple::ArchType> CCCClangArchs; - /// Certain options suppress the 'no input files' warning. bool SuppressMissingInputWarning : 1; @@ -232,9 +215,6 @@ public: InstalledDir = Value; } - bool shouldForceClangUse() const { return ForcedClangUse; } - void setForcedClangUse(bool V = true) { ForcedClangUse = V; } - /// @} /// @name Primary Functionality /// @{ @@ -287,7 +267,7 @@ public: /// BuildJobs - Bind actions to concrete tools and translate /// arguments to form the list of jobs to run. /// - /// \arg C - The compilation that is being built. + /// \param C - The compilation that is being built. void BuildJobs(Compilation &C) const; /// ExecuteCompilation - Execute the compilation according to the command line @@ -323,26 +303,21 @@ public: /// PrintVersion - Print the driver version. void PrintVersion(const Compilation &C, raw_ostream &OS) const; - /// GetFilePath - Lookup \arg Name in the list of file search paths. + /// GetFilePath - Lookup \p Name in the list of file search paths. /// - /// \arg TC - The tool chain for additional information on + /// \param TC - The tool chain for additional information on /// directories to search. // // FIXME: This should be in CompilationInfo. std::string GetFilePath(const char *Name, const ToolChain &TC) const; - /// GetProgramPath - Lookup \arg Name in the list of program search - /// paths. + /// GetProgramPath - Lookup \p Name in the list of program search paths. /// - /// \arg TC - The provided tool chain for additional information on + /// \param TC - The provided tool chain for additional information on /// directories to search. - /// - /// \arg WantFile - False when searching for an executable file, otherwise - /// true. Defaults to false. // // FIXME: This should be in CompilationInfo. - std::string GetProgramPath(const char *Name, const ToolChain &TC, - bool WantFile = false) const; + std::string GetProgramPath(const char *Name, const ToolChain &TC) const; /// HandleImmediateArgs - Handle any arguments which should be /// treated before building actions or binding tools. @@ -352,14 +327,14 @@ public: bool HandleImmediateArgs(const Compilation &C); /// ConstructAction - Construct the appropriate action to do for - /// \arg Phase on the \arg Input, taking in to account arguments + /// \p Phase on the \p Input, taking in to account arguments /// like -fsyntax-only or --analyze. Action *ConstructPhaseAction(const ArgList &Args, phases::ID Phase, Action *Input) const; /// BuildJobsForAction - Construct the jobs to perform for the - /// action \arg A. + /// action \p A. void BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, @@ -369,7 +344,7 @@ public: InputInfo &Result) const; /// GetNamedOutputPath - Return the name to use for the output of - /// the action \arg JA. The result is appended to the compilation's + /// the action \p JA. The result is appended to the compilation's /// list of temporary or result files, as appropriate. /// /// \param C - The compilation. diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Job.h b/contrib/llvm/tools/clang/include/clang/Driver/Job.h index c94886d..84f5ee1 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Job.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Job.h @@ -39,8 +39,6 @@ public: /// addCommand - Append a command to the current job, which must be /// either a piped job or a job list. void addCommand(Command *C); - - static bool classof(const Job *) { return true; } }; /// Command - An executable path/name and argument vector to @@ -78,7 +76,6 @@ public: static bool classof(const Job *J) { return J->getKind() == CommandClass; } - static bool classof(const Command *) { return true; } }; /// JobList - A sequence of jobs to perform. @@ -113,7 +110,6 @@ public: static bool classof(const Job *J) { return J->getKind() == JobListClass; } - static bool classof(const JobList *) { return true; } }; } // end namespace driver diff --git a/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td b/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td index 9e6d5b9..d16a2a7 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td @@ -88,6 +88,9 @@ def NoForward : OptionFlag; // CC1Option - This option should be accepted by clang -cc1. def CC1Option : OptionFlag; +// NoDriverOption - This option should not be accepted by the driver. +def NoDriverOption : OptionFlag; + // Define the option group class. class OptionGroup<string name> { @@ -99,8 +102,9 @@ class OptionGroup<string name> { // Define the option class. -class Option<string name, OptionKind kind> { +class Option<list<string> prefixes, string name, OptionKind kind> { string EnumName = ?; // Uses the def name if undefined. + list<string> Prefixes = prefixes; string Name = name; OptionKind Kind = kind; // Used by MultiArg option kind. @@ -114,15 +118,22 @@ class Option<string name, OptionKind kind> { // Helpers for defining options. -class Flag<string name> : Option<name, KIND_FLAG>; -class Joined<string name> : Option<name, KIND_JOINED>; -class Separate<string name> : Option<name, KIND_SEPARATE>; -class CommaJoined<string name> : Option<name, KIND_COMMAJOINED>; -class MultiArg<string name, int numargs> : Option<name, KIND_MULTIARG> { +class Flag<list<string> prefixes, string name> + : Option<prefixes, name, KIND_FLAG>; +class Joined<list<string> prefixes, string name> + : Option<prefixes, name, KIND_JOINED>; +class Separate<list<string> prefixes, string name> + : Option<prefixes, name, KIND_SEPARATE>; +class CommaJoined<list<string> prefixes, string name> + : Option<prefixes, name, KIND_COMMAJOINED>; +class MultiArg<list<string> prefixes, string name, int numargs> + : Option<prefixes, name, KIND_MULTIARG> { int NumArgs = numargs; } -class JoinedOrSeparate<string name> : Option<name, KIND_JOINED_OR_SEPARATE>; -class JoinedAndSeparate<string name> : Option<name, KIND_JOINED_AND_SEPARATE>; +class JoinedOrSeparate<list<string> prefixes, string name> + : Option<prefixes, name, KIND_JOINED_OR_SEPARATE>; +class JoinedAndSeparate<list<string> prefixes, string name> + : Option<prefixes, name, KIND_JOINED_AND_SEPARATE>; // Mix-ins for adding optional attributes. @@ -137,5 +148,5 @@ class MetaVarName<string name> { string MetaVarName = name; } // FIXME: Have generator validate that these appear in correct position (and // aren't duplicated). -def INPUT : Option<"<input>", KIND_INPUT>, Flags<[DriverOption,CC1Option]>; -def UNKNOWN : Option<"<unknown>", KIND_UNKNOWN>; +def INPUT : Option<[], "<input>", KIND_INPUT>, Flags<[DriverOption,CC1Option]>; +def UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN>; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h b/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h index 27bd119..53d83a0 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h @@ -12,24 +12,10 @@ #include "clang/Basic/LLVM.h" #include "clang/Driver/OptSpecifier.h" +#include "llvm/ADT/StringSet.h" namespace clang { namespace driver { -namespace options { - enum DriverFlag { - DriverOption = (1 << 0), - HelpHidden = (1 << 1), - LinkerInput = (1 << 2), - NoArgumentUnused = (1 << 3), - NoForward = (1 << 4), - RenderAsInput = (1 << 5), - RenderJoined = (1 << 6), - RenderSeparate = (1 << 7), - Unsupported = (1 << 8), - CC1Option = (1 << 9) - }; -} - class Arg; class ArgList; class InputArgList; @@ -46,9 +32,13 @@ namespace options { public: /// \brief Entry for a single option instance in the option data table. struct Info { + /// A null terminated array of prefix strings to apply to name while + /// matching. + const char *const *Prefixes; const char *Name; const char *HelpText; const char *MetaVar; + unsigned ID; unsigned char Kind; unsigned char Param; unsigned short Flags; @@ -61,19 +51,18 @@ namespace options { const Info *OptionInfos; unsigned NumOptionInfos; - /// \brief The lazily constructed options table, indexed by option::ID - 1. - mutable Option **Options; - - /// \brief Prebound input option instance. - const Option *TheInputOption; - - /// \brief Prebound unknown option instance. - const Option *TheUnknownOption; + unsigned TheInputOptionID; + unsigned TheUnknownOptionID; /// The index of the first option which can be parsed (i.e., is not a /// special option like 'input' or 'unknown', and is not an option group). unsigned FirstSearchableIndex; + /// The union of all option prefixes. If an argument does not begin with + /// one of these, it is an input. + llvm::StringSet<> PrefixesUnion; + std::string PrefixChars; + private: const Info &getInfo(OptSpecifier Opt) const { unsigned id = Opt.getID(); @@ -81,8 +70,6 @@ namespace options { return OptionInfos[id - 1]; } - Option *CreateOption(unsigned id) const; - protected: OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos); public: @@ -95,17 +82,7 @@ namespace options { /// if necessary. /// /// \return The option, or null for the INVALID option id. - const Option *getOption(OptSpecifier Opt) const { - unsigned id = Opt.getID(); - if (id == 0) - return 0; - - assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID."); - Option *&Entry = Options[id - 1]; - if (!Entry) - Entry = CreateOption(id); - return Entry; - } + const Option getOption(OptSpecifier Opt) const; /// \brief Lookup the name of the given option. const char *getOptionName(OptSpecifier id) const { @@ -122,11 +99,6 @@ namespace options { return getInfo(id).GroupID; } - /// \brief Should the help for the given option be hidden by default. - bool isOptionHelpHidden(OptSpecifier id) const { - return getInfo(id).Flags & options::HelpHidden; - } - /// \brief Get the help text to use to describe this option. const char *getOptionHelpText(OptSpecifier id) const { return getInfo(id).HelpText; @@ -176,9 +148,12 @@ namespace options { /// \param OS - The stream to write the help text to. /// \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. + /// \param FlagsToInclude - If non-zero, only include options with any + /// of these flags set. + /// \param FlagsToExclude - Exclude options with any of these flags set. void PrintHelp(raw_ostream &OS, const char *Name, - const char *Title, bool ShowHidden = false) const; + const char *Title, unsigned short FlagsToInclude = 0, + unsigned short FlagsToExclude = 0) const; }; } } diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Option.h b/contrib/llvm/tools/clang/include/clang/Driver/Option.h index e6c4e12..c3db773 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Option.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Option.h @@ -10,15 +10,36 @@ #ifndef CLANG_DRIVER_OPTION_H_ #define CLANG_DRIVER_OPTION_H_ -#include "clang/Driver/OptSpecifier.h" +#include "clang/Driver/OptTable.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorHandling.h" #include "clang/Basic/LLVM.h" namespace clang { namespace driver { class Arg; class ArgList; - class OptionGroup; + +namespace options { + /// Base flags for all options. Custom flags may be added after. + enum DriverFlag { + HelpHidden = (1 << 0), + RenderAsInput = (1 << 1), + RenderJoined = (1 << 2), + RenderSeparate = (1 << 3) + }; + + /// Flags specifically for clang options. + enum ClangFlags { + DriverOption = (1 << 4), + LinkerInput = (1 << 5), + NoArgumentUnused = (1 << 6), + NoForward = (1 << 7), + Unsupported = (1 << 8), + CC1Option = (1 << 9), + NoDriverOption = (1 << 10) + }; +} /// Option - Abstract representation for a single form of driver /// argument. @@ -53,100 +74,104 @@ namespace driver { RenderValuesStyle }; - private: - OptionClass Kind; - - /// The option ID. - OptSpecifier ID; - - /// The option name. - StringRef Name; - - /// Group this option is a member of, if any. - const OptionGroup *Group; - - /// Option that this is an alias for, if any. - const Option *Alias; - - /// Unsupported options will be rejected. - bool Unsupported : 1; - - /// Treat this option like a linker input? - bool LinkerInput : 1; - - /// When rendering as an input, don't render the option. + protected: + const OptTable::Info *Info; + const OptTable *Owner; - // FIXME: We should ditch the render/renderAsInput distinction. - bool NoOptAsInput : 1; + public: + Option(const OptTable::Info *Info, const OptTable *Owner); + ~Option(); - /// The style to using when rendering arguments parsed by this option. - unsigned RenderStyle : 2; + bool isValid() const { + return Info != 0; + } - /// This option is only consumed by the driver. - bool DriverOption : 1; + unsigned getID() const { + assert(Info && "Must have a valid info!"); + return Info->ID; + } - /// This option should not report argument unused errors. - bool NoArgumentUnused : 1; + OptionClass getKind() const { + assert(Info && "Must have a valid info!"); + return OptionClass(Info->Kind); + } - /// This option should not be implicitly forwarded. - bool NoForward : 1; + /// \brief Get the name of this option without any prefix. + StringRef getName() const { + assert(Info && "Must have a valid info!"); + return Info->Name; + } - /// CC1Option - This option should be accepted by clang -cc1. - bool CC1Option : 1; + const Option getGroup() const { + assert(Info && "Must have a valid info!"); + assert(Owner && "Must have a valid owner!"); + return Owner->getOption(Info->GroupID); + } - protected: - Option(OptionClass Kind, OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - public: - virtual ~Option(); + const Option getAlias() const { + assert(Info && "Must have a valid info!"); + assert(Owner && "Must have a valid owner!"); + return Owner->getOption(Info->AliasID); + } - unsigned getID() const { return ID.getID(); } - OptionClass getKind() const { return Kind; } - StringRef getName() const { return Name; } - const OptionGroup *getGroup() const { return Group; } - const Option *getAlias() const { return Alias; } + /// \brief Get the default prefix for this option. + StringRef getPrefix() const { + const char *Prefix = *Info->Prefixes; + return Prefix ? Prefix : StringRef(); + } - bool isUnsupported() const { return Unsupported; } - void setUnsupported(bool Value) { Unsupported = Value; } + /// \brief Get the name of this option with the default prefix. + std::string getPrefixedName() const { + std::string Ret = getPrefix(); + Ret += getName(); + return Ret; + } - bool isLinkerInput() const { return LinkerInput; } - void setLinkerInput(bool Value) { LinkerInput = Value; } + unsigned getNumArgs() const { return Info->Param; } - bool hasNoOptAsInput() const { return NoOptAsInput; } - void setNoOptAsInput(bool Value) { NoOptAsInput = Value; } + bool hasNoOptAsInput() const { return Info->Flags & options::RenderAsInput;} RenderStyleKind getRenderStyle() const { - return RenderStyleKind(RenderStyle); + if (Info->Flags & options::RenderJoined) + return RenderJoinedStyle; + if (Info->Flags & options::RenderSeparate) + return RenderSeparateStyle; + switch (getKind()) { + case GroupClass: + case InputClass: + case UnknownClass: + return RenderValuesStyle; + case JoinedClass: + case JoinedAndSeparateClass: + return RenderJoinedStyle; + case CommaJoinedClass: + return RenderCommaJoinedStyle; + case FlagClass: + case SeparateClass: + case MultiArgClass: + case JoinedOrSeparateClass: + return RenderSeparateStyle; + } + llvm_unreachable("Unexpected kind!"); } - void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; } - - bool isDriverOption() const { return DriverOption; } - void setDriverOption(bool Value) { DriverOption = Value; } - bool hasNoArgumentUnused() const { return NoArgumentUnused; } - void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; } - - bool hasNoForward() const { return NoForward; } - void setNoForward(bool Value) { NoForward = Value; } - - bool isCC1Option() const { return CC1Option; } - void setIsCC1Option(bool Value) { CC1Option = Value; } - - bool hasForwardToGCC() const { - return !NoForward && !DriverOption && !LinkerInput; + /// Test if this option has the flag \a Val. + bool hasFlag(unsigned Val) const { + return Info->Flags & Val; } /// getUnaliasedOption - Return the final option this option /// aliases (itself, if the option has no alias). - const Option *getUnaliasedOption() const { - if (Alias) return Alias->getUnaliasedOption(); - return this; + const Option getUnaliasedOption() const { + const Option Alias = getAlias(); + if (Alias.isValid()) return Alias.getUnaliasedOption(); + return *this; } /// getRenderName - Return the name to use when rendering this /// option. StringRef getRenderName() const { - return getUnaliasedOption()->getName(); + return getUnaliasedOption().getName(); } /// matches - Predicate for whether this option is part of the @@ -164,158 +189,13 @@ namespace driver { /// If the option accepts the current argument, accept() sets /// Index to the position where argument parsing should resume /// (even if the argument is missing values). - virtual Arg *accept(const ArgList &Args, unsigned &Index) const = 0; + /// + /// \parm ArgSize The number of bytes taken up by the matched Option prefix + /// and name. This is used to determine where joined values + /// start. + Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const; void dump() const; - - static bool classof(const Option *) { return true; } - }; - - /// OptionGroup - A set of options which are can be handled uniformly - /// by the driver. - class OptionGroup : public Option { - public: - OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::GroupClass; - } - static bool classof(const OptionGroup *) { return true; } - }; - - // Dummy option classes. - - /// InputOption - Dummy option class for representing driver inputs. - class InputOption : public Option { - public: - InputOption(OptSpecifier ID); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::InputClass; - } - static bool classof(const InputOption *) { return true; } - }; - - /// UnknownOption - Dummy option class for represent unknown arguments. - class UnknownOption : public Option { - public: - UnknownOption(OptSpecifier ID); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::UnknownClass; - } - static bool classof(const UnknownOption *) { return true; } - }; - - // Normal options. - - class FlagOption : public Option { - public: - FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, - const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::FlagClass; - } - static bool classof(const FlagOption *) { return true; } - }; - - class JoinedOption : public Option { - public: - JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, - const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::JoinedClass; - } - static bool classof(const JoinedOption *) { return true; } - }; - - class SeparateOption : public Option { - public: - SeparateOption(OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::SeparateClass; - } - static bool classof(const SeparateOption *) { return true; } - }; - - class CommaJoinedOption : public Option { - public: - CommaJoinedOption(OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::CommaJoinedClass; - } - static bool classof(const CommaJoinedOption *) { return true; } - }; - - // FIXME: Fold MultiArgOption into SeparateOption? - - /// MultiArgOption - An option which takes multiple arguments (these - /// are always separate arguments). - class MultiArgOption : public Option { - unsigned NumArgs; - - public: - MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, - const Option *Alias, unsigned NumArgs); - - unsigned getNumArgs() const { return NumArgs; } - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::MultiArgClass; - } - static bool classof(const MultiArgOption *) { return true; } - }; - - /// JoinedOrSeparateOption - An option which either literally - /// prefixes its (non-empty) value, or is follwed by a value. - class JoinedOrSeparateOption : public Option { - public: - JoinedOrSeparateOption(OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::JoinedOrSeparateClass; - } - static bool classof(const JoinedOrSeparateOption *) { return true; } - }; - - /// JoinedAndSeparateOption - An option which literally prefixes its - /// value and is followed by another value. - class JoinedAndSeparateOption : public Option { - public: - JoinedAndSeparateOption(OptSpecifier ID, const char *Name, - const OptionGroup *Group, const Option *Alias); - - virtual Arg *accept(const ArgList &Args, unsigned &Index) const; - - static bool classof(const Option *O) { - return O->getKind() == Option::JoinedAndSeparateClass; - } - static bool classof(const JoinedAndSeparateOption *) { return true; } }; } // end namespace driver diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Options.h b/contrib/llvm/tools/clang/include/clang/Driver/Options.h index ac312cd..6c114e2 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Options.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Options.h @@ -17,11 +17,13 @@ namespace driver { namespace options { enum ID { OPT_INVALID = 0, // This is not an option ID. -#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ +#define PREFIX(NAME, VALUE) +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ HELPTEXT, METAVAR) OPT_##ID, #include "clang/Driver/Options.inc" LastOption #undef OPTION +#undef PREFIX }; } diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Options.td b/contrib/llvm/tools/clang/include/clang/Driver/Options.td index dee0dfb..ca4f6d5 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Options.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/Options.td @@ -1,4 +1,4 @@ -//===--- DriverOptions.td - Options for clang -----------------------------===// +//===--- Options.td - Options for clang -----------------------------------===// // // The LLVM Compiler Infrastructure // @@ -41,6 +41,8 @@ def m_x86_Features_Group : OptionGroup<"<m x86 features group>">, Group<m_Group def m_hexagon_Features_Group : OptionGroup<"<m hexagon features group>">, Group<m_Group>; def opencl_Group : OptionGroup<"<opencl group>">; def u_Group : OptionGroup<"<u group>">; +def mips_CPUs_Group : OptionGroup<"<MIPS CPU aliases group>">, + Group<CompileOnly_Group>; def pedantic_Group : OptionGroup<"<pedantic group>">, Group<CompileOnly_Group>; @@ -82,1094 +84,1073 @@ def ccc_debug_Group : OptionGroup<"<clang debug/development internal options>">, Group<ccc_Group>, HelpText<"DEBUG/DEVELOPMENT OPTIONS">; class CCCDriverOpt : Group<ccc_driver_Group>, Flags<[DriverOption, HelpHidden]>; -def ccc_cxx : Flag<"-ccc-cxx">, CCCDriverOpt, +def ccc_cxx : Flag<["-"], "ccc-cxx">, CCCDriverOpt, HelpText<"Act as a C++ driver">; -def ccc_echo : Flag<"-ccc-echo">, CCCDriverOpt, +def ccc_echo : Flag<["-"], "ccc-echo">, CCCDriverOpt, HelpText<"Echo commands before running them">; -def ccc_gcc_name : Separate<"-ccc-gcc-name">, CCCDriverOpt, +def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, CCCDriverOpt, HelpText<"Name for native GCC compiler">, MetaVarName<"<gcc-path>">; -def ccc_clang_cxx : Flag<"-ccc-clang-cxx">, CCCDriverOpt, - HelpText<"Enable the clang compiler for C++">; -def ccc_no_clang_cxx : Flag<"-ccc-no-clang-cxx">, CCCDriverOpt, - HelpText<"Disable the clang compiler for C++">; -def ccc_no_clang : Flag<"-ccc-no-clang">, CCCDriverOpt, - HelpText<"Disable the clang compiler">; -def ccc_no_clang_cpp : Flag<"-ccc-no-clang-cpp">, CCCDriverOpt, - HelpText<"Disable the clang preprocessor">; -def ccc_clang_archs : Separate<"-ccc-clang-archs">, CCCDriverOpt, +def ccc_clang_archs : Separate<["-"], "ccc-clang-archs">, CCCDriverOpt, HelpText<"Comma separate list of architectures to use the clang compiler for">, MetaVarName<"<arch-list>">; -def ccc_pch_is_pch : Flag<"-ccc-pch-is-pch">, CCCDriverOpt, +def ccc_pch_is_pch : Flag<["-"], "ccc-pch-is-pch">, CCCDriverOpt, HelpText<"Use lazy PCH for precompiled headers">; -def ccc_pch_is_pth : Flag<"-ccc-pch-is-pth">, CCCDriverOpt, +def ccc_pch_is_pth : Flag<["-"], "ccc-pch-is-pth">, CCCDriverOpt, HelpText<"Use pretokenized headers for precompiled headers">; class CCCDebugOpt : Group<ccc_debug_Group>, Flags<[DriverOption, HelpHidden]>; -def ccc_install_dir : Separate<"-ccc-install-dir">, CCCDebugOpt, +def ccc_install_dir : Separate<["-"], "ccc-install-dir">, CCCDebugOpt, HelpText<"Simulate installation in the given directory">; -def ccc_print_options : Flag<"-ccc-print-options">, CCCDebugOpt, +def ccc_print_options : Flag<["-"], "ccc-print-options">, CCCDebugOpt, HelpText<"Dump parsed command line arguments">; -def ccc_print_phases : Flag<"-ccc-print-phases">, CCCDebugOpt, +def ccc_print_phases : Flag<["-"], "ccc-print-phases">, CCCDebugOpt, HelpText<"Dump list of actions to perform">; -def ccc_print_bindings : Flag<"-ccc-print-bindings">, CCCDebugOpt, +def ccc_print_bindings : Flag<["-"], "ccc-print-bindings">, CCCDebugOpt, HelpText<"Show bindings of tools to actions">; -def ccc_arcmt_check : Flag<"-ccc-arcmt-check">, CCCDriverOpt, +def ccc_arcmt_check : Flag<["-"], "ccc-arcmt-check">, CCCDriverOpt, HelpText<"Check for ARC migration issues that need manual handling">; -def ccc_arcmt_modify : Flag<"-ccc-arcmt-modify">, CCCDriverOpt, +def ccc_arcmt_modify : Flag<["-"], "ccc-arcmt-modify">, CCCDriverOpt, HelpText<"Apply modifications to files to conform to ARC">; -def ccc_arrmt_check : Flag<"-ccc-arrmt-check">, Alias<ccc_arcmt_check>; -def ccc_arrmt_modify : Flag<"-ccc-arrmt-modify">, Alias<ccc_arcmt_modify>; -def ccc_arcmt_migrate : Separate<"-ccc-arcmt-migrate">, CCCDriverOpt, +def ccc_arrmt_check : Flag<["-"], "ccc-arrmt-check">, Alias<ccc_arcmt_check>; +def ccc_arrmt_modify : Flag<["-"], "ccc-arrmt-modify">, Alias<ccc_arcmt_modify>; +def ccc_arcmt_migrate : Separate<["-"], "ccc-arcmt-migrate">, CCCDriverOpt, HelpText<"Apply modifications and produces temporary files that conform to ARC">; -def arcmt_migrate_report_output : Separate<"-arcmt-migrate-report-output">, +def arcmt_migrate_report_output : Separate<["-"], "arcmt-migrate-report-output">, HelpText<"Output path for the plist report">, Flags<[CC1Option]>; -def arcmt_migrate_emit_arc_errors : Flag<"-arcmt-migrate-emit-errors">, +def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">, HelpText<"Emit ARC errors even if the migrator can fix them">, Flags<[CC1Option]>; -def _migrate : Flag<"--migrate">, Flags<[DriverOption]>, +def _migrate : Flag<["--"], "migrate">, Flags<[DriverOption]>, HelpText<"Run the migrator">; -def ccc_objcmt_migrate : Separate<"-ccc-objcmt-migrate">, CCCDriverOpt, +def ccc_objcmt_migrate : Separate<["-"], "ccc-objcmt-migrate">, CCCDriverOpt, HelpText<"Apply modifications and produces temporary files to migrate to " "modern ObjC syntax">; -def objcmt_migrate_literals : Flag<"-objcmt-migrate-literals">, Flags<[CC1Option]>, +def objcmt_migrate_literals : Flag<["-"], "objcmt-migrate-literals">, Flags<[CC1Option]>, HelpText<"Enable migration to modern ObjC literals">; -def objcmt_migrate_subscripting : Flag<"-objcmt-migrate-subscripting">, Flags<[CC1Option]>, +def objcmt_migrate_subscripting : Flag<["-"], "objcmt-migrate-subscripting">, Flags<[CC1Option]>, HelpText<"Enable migration to modern ObjC subscripting">; // Make sure all other -ccc- options are rejected. -def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>; +def ccc_ : Joined<["-"], "ccc-">, Group<ccc_Group>, Flags<[Unsupported]>; // Standard Options -def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>, +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">, Flags<[CC1Option]>; -def C : Flag<"-C">, Flags<[CC1Option]>; -def D : JoinedOrSeparate<"-D">, Group<CompileOnly_Group>, Flags<[CC1Option]>; -def E : Flag<"-E">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>, +def _DASH_DASH : Flag<["--"], "">, Flags<[DriverOption]>; +def A : JoinedOrSeparate<["-"], "A">; +def B : JoinedOrSeparate<["-"], "B">; +def CC : Flag<["-"], "CC">, Flags<[CC1Option]>; +def C : Flag<["-"], "C">, Flags<[CC1Option]>; +def D : JoinedOrSeparate<["-"], "D">, Group<CompileOnly_Group>, Flags<[CC1Option]>; +def E : Flag<["-"], "E">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>, HelpText<"Only run the preprocessor">; -def F : JoinedOrSeparate<"-F">, Flags<[RenderJoined,CC1Option]>, +def F : JoinedOrSeparate<["-"], "F">, Flags<[RenderJoined,CC1Option]>, HelpText<"Add directory to framework include search path">; -def G : Separate<"-G">, Flags<[DriverOption]>; -def H : Flag<"-H">, Flags<[CC1Option]>, +def G : Separate<["-"], "G">, Flags<[DriverOption]>; +def H : Flag<["-"], "H">, Flags<[CC1Option]>, HelpText<"Show header includes and nesting depth">; -def I_ : Flag<"-I-">, Group<I_Group>; -def I : JoinedOrSeparate<"-I">, Group<I_Group>, Flags<[CC1Option]>, +def I_ : Flag<["-"], "I-">, Group<I_Group>; +def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>, Flags<[CC1Option]>, HelpText<"Add directory to include search path">; -def L : JoinedOrSeparate<"-L">, Flags<[RenderJoined]>; -def MD : Flag<"-MD">, Group<M_Group>; -def MF : JoinedOrSeparate<"-MF">, Group<M_Group>; -def MG : Flag<"-MG">, Group<M_Group>, Flags<[CC1Option]>, +def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>; +def MD : Flag<["-"], "MD">, Group<M_Group>; +def MF : JoinedOrSeparate<["-"], "MF">, Group<M_Group>; +def MG : Flag<["-"], "MG">, Group<M_Group>, Flags<[CC1Option]>, HelpText<"Add missing headers to dependency list">; -def MMD : Flag<"-MMD">, Group<M_Group>; -def MM : Flag<"-MM">, Group<M_Group>; -def MP : Flag<"-MP">, Group<M_Group>, Flags<[CC1Option]>, +def MMD : Flag<["-"], "MMD">, Group<M_Group>; +def MM : Flag<["-"], "MM">, Group<M_Group>; +def MP : Flag<["-"], "MP">, Group<M_Group>, Flags<[CC1Option]>, HelpText<"Create phony target for each dependency (other than main file)">; -def MQ : JoinedOrSeparate<"-MQ">, Group<M_Group>, Flags<[CC1Option]>, +def MQ : JoinedOrSeparate<["-"], "MQ">, Group<M_Group>, Flags<[CC1Option]>, HelpText<"Specify target to quote for dependency">; -def MT : JoinedOrSeparate<"-MT">, Group<M_Group>, Flags<[CC1Option]>, +def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>, Flags<[CC1Option]>, HelpText<"Specify target for dependency">; -def Mach : Flag<"-Mach">; -def M : Flag<"-M">, Group<M_Group>; -def O0 : Joined<"-O0">, Group<O_Group>, Flags<[CC1Option]>; -def O4 : Joined<"-O4">, Group<O_Group>, Flags<[CC1Option]>; -def ObjCXX : Flag<"-ObjC++">, Flags<[DriverOption]>, +def Mach : Flag<["-"], "Mach">; +def M : Flag<["-"], "M">, Group<M_Group>; +def O0 : Joined<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>; +def O4 : Joined<["-"], "O4">, Group<O_Group>, Flags<[CC1Option]>; +def ObjCXX : Flag<["-"], "ObjC++">, Flags<[DriverOption]>, HelpText<"Treat source input files as Objective-C++ inputs">; -def ObjC : Flag<"-ObjC">, Flags<[DriverOption]>, +def ObjC : Flag<["-"], "ObjC">, Flags<[DriverOption]>, HelpText<"Treat source input files as Objective-C inputs">; -def O : Joined<"-O">, Group<O_Group>, Flags<[CC1Option]>; -def P : Flag<"-P">, Flags<[CC1Option]>, +def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option]>; +def P : Flag<["-"], "P">, Flags<[CC1Option]>, HelpText<"Disable linemarker output in -E mode">; -def Qn : Flag<"-Qn">; -def Qunused_arguments : Flag<"-Qunused-arguments">, Flags<[DriverOption]>, +def Qn : Flag<["-"], "Qn">; +def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption]>, HelpText<"Don't emit warning for unused driver arguments">; -def Q : Flag<"-Q">; -def R : Flag<"-R">; -def S : Flag<"-S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>, +def Q : Flag<["-"], "Q">; +def R : Flag<["-"], "R">; +def S : Flag<["-"], "S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>, HelpText<"Only run preprocess and compilation steps">; -def Tbss : JoinedOrSeparate<"-Tbss">, Group<T_Group>; -def Tdata : JoinedOrSeparate<"-Tdata">, Group<T_Group>; -def Ttext : JoinedOrSeparate<"-Ttext">, Group<T_Group>; -def T : JoinedOrSeparate<"-T">, Group<T_Group>; -def U : JoinedOrSeparate<"-U">, Group<CompileOnly_Group>, Flags<[CC1Option]>; -def V : JoinedOrSeparate<"-V">, Flags<[DriverOption, Unsupported]>; -def Wa_COMMA : CommaJoined<"-Wa,">, +def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>; +def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group<T_Group>; +def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group<T_Group>; +def T : JoinedOrSeparate<["-"], "T">, Group<T_Group>; +def U : JoinedOrSeparate<["-"], "U">, Group<CompileOnly_Group>, Flags<[CC1Option]>; +def V : JoinedOrSeparate<["-"], "V">, Flags<[DriverOption, Unsupported]>; +def Wa_COMMA : CommaJoined<["-"], "Wa,">, HelpText<"Pass the comma separated arguments in <arg> to the assembler">, MetaVarName<"<arg>">; -def Wall : Flag<"-Wall">, Group<W_Group>, Flags<[CC1Option]>; -def Wdeprecated : Flag<"-Wdeprecated">, Group<W_Group>, Flags<[CC1Option]>; -def Wno_deprecated : Flag<"-Wno-deprecated">, Group<W_Group>, Flags<[CC1Option]>; -def Wextra : Flag<"-Wextra">, Group<W_Group>, Flags<[CC1Option]>; -def Wl_COMMA : CommaJoined<"-Wl,">, Flags<[LinkerInput, RenderAsInput]>, +def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[CC1Option]>; +def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>, Flags<[CC1Option]>; +def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group<W_Group>, Flags<[CC1Option]>; +def Wextra : Flag<["-"], "Wextra">, Group<W_Group>, Flags<[CC1Option]>; +def Wl_COMMA : CommaJoined<["-"], "Wl,">, Flags<[LinkerInput, RenderAsInput]>, HelpText<"Pass the comma separated arguments in <arg> to the linker">, MetaVarName<"<arg>">; -def Wno_nonportable_cfstrings : Joined<"-Wno-nonportable-cfstrings">, Group<W_Group>, +def Wno_nonportable_cfstrings : Joined<["-"], "Wno-nonportable-cfstrings">, Group<W_Group>, Flags<[CC1Option]>; -def Wnonportable_cfstrings : Joined<"-Wnonportable-cfstrings">, Group<W_Group>, +def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group<W_Group>, Flags<[CC1Option]>; -def Wp_COMMA : CommaJoined<"-Wp,">, +def Wp_COMMA : CommaJoined<["-"], "Wp,">, HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">, MetaVarName<"<arg>">; -def Wwrite_strings : Flag<"-Wwrite-strings">, Group<W_Group>, Flags<[CC1Option]>; -def Wno_write_strings : Flag<"-Wno-write-strings">, Group<W_Group>, Flags<[CC1Option]>; -def W_Joined : Joined<"-W">, Group<W_Group>, Flags<[CC1Option]>; -def Xanalyzer : Separate<"-Xanalyzer">, +def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option]>; +def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option]>; +def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option]>, + MetaVarName<"<warning>">, HelpText<"Enable the specified warning">; +def Xanalyzer : Separate<["-"], "Xanalyzer">, HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">; -def Xarch__ : JoinedAndSeparate<"-Xarch_">, Flags<[DriverOption]>; -def Xassembler : Separate<"-Xassembler">, +def Xarch__ : JoinedAndSeparate<["-"], "Xarch_">, Flags<[DriverOption]>; +def Xassembler : Separate<["-"], "Xassembler">, HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">; -def Xclang : Separate<"-Xclang">, +def Xclang : Separate<["-"], "Xclang">, HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">, Flags<[NoForward]>; -def Xlinker : Separate<"-Xlinker">, Flags<[LinkerInput, RenderAsInput]>, +def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>, HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">; -def Xpreprocessor : Separate<"-Xpreprocessor">, +def Xpreprocessor : Separate<["-"], "Xpreprocessor">, HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">; -def X_Flag : Flag<"-X">; -def X_Joined : Joined<"-X">; -def Z_Flag : Flag<"-Z">; -def Z_Joined : Joined<"-Z">; -def all__load : Flag<"-all_load">; -def allowable__client : Separate<"-allowable_client">; -def ansi : Flag<"-ansi">, Group<a_Group>; -def arch__errors__fatal : Flag<"-arch_errors_fatal">; -def arch : Separate<"-arch">, Flags<[DriverOption]>; -def arch__only : Separate<"-arch_only">; -def a : Joined<"-a">, Group<a_Group>; -def bind__at__load : Flag<"-bind_at_load">; -def bundle__loader : Separate<"-bundle_loader">; -def bundle : Flag<"-bundle">; -def b : JoinedOrSeparate<"-b">, Flags<[Unsupported]>; -def cl_kernel_arg_info : Flag<"-cl-kernel-arg-info">, Flags<[CC1Option]>, Group<opencl_Group>, +def X_Flag : Flag<["-"], "X">; +def X_Joined : Joined<["-"], "X">; +def Z_Flag : Flag<["-"], "Z">; +def Z_Joined : Joined<["-"], "Z">; +def all__load : Flag<["-"], "all_load">; +def allowable__client : Separate<["-"], "allowable_client">; +def ansi : Flag<["-", "--"], "ansi">, Group<a_Group>; +def arch__errors__fatal : Flag<["-"], "arch_errors_fatal">; +def arch : Separate<["-"], "arch">, Flags<[DriverOption]>; +def arch__only : Separate<["-"], "arch_only">; +def a : Joined<["-"], "a">, Group<a_Group>; +def bind__at__load : Flag<["-"], "bind_at_load">; +def bundle__loader : Separate<["-"], "bundle_loader">; +def bundle : Flag<["-"], "bundle">; +def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>; +def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, Flags<[CC1Option]>, Group<opencl_Group>, HelpText<"OpenCL only. This option allows the compiler to store information about the arguments of a kernel(s)"> ; -def client__name : JoinedOrSeparate<"-client_name">; -def combine : Flag<"-combine">, Flags<[DriverOption, Unsupported]>; -def compatibility__version : JoinedOrSeparate<"-compatibility_version">; -def coverage : Flag<"-coverage">; -def cpp_precomp : Flag<"-cpp-precomp">, Group<clang_ignored_f_Group>; -def current__version : JoinedOrSeparate<"-current_version">; -def cxx_isystem : JoinedOrSeparate<"-cxx-isystem">, Group<clang_i_Group>, +def client__name : JoinedOrSeparate<["-"], "client_name">; +def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>; +def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">; +def coverage : Flag<["-", "--"], "coverage">; +def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>; +def current__version : JoinedOrSeparate<["-"], "current_version">; +def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>, HelpText<"Add directory to the C++ SYSTEM include search path">, Flags<[CC1Option]>, MetaVarName<"<directory>">; -def c : Flag<"-c">, Flags<[DriverOption]>, +def c : Flag<["-"], "c">, Flags<[DriverOption]>, HelpText<"Only run preprocess, compile, and assemble steps">; -def dA : Flag<"-dA">, Group<d_Group>; -def dD : Flag<"-dD">, Group<d_Group>, Flags<[CC1Option]>, +def dA : Flag<["-"], "dA">, Group<d_Group>; +def dD : Flag<["-"], "dD">, Group<d_Group>, Flags<[CC1Option]>, HelpText<"Print macro definitions in -E mode in addition to normal output">; -def dM : Flag<"-dM">, Group<d_Group>, Flags<[CC1Option]>, +def dM : Flag<["-"], "dM">, Group<d_Group>, Flags<[CC1Option]>, HelpText<"Print macro definitions in -E mode instead of normal output">; -def dead__strip : Flag<"-dead_strip">; -def dependency_file : Separate<"-dependency-file">, Flags<[CC1Option]>, +def dead__strip : Flag<["-"], "dead_strip">; +def dependency_file : Separate<["-"], "dependency-file">, Flags<[CC1Option]>, HelpText<"Filename (or -) to write dependency output to">; -def dependency_dot : Separate<"-dependency-dot">, Flags<[CC1Option]>, +def dependency_dot : Separate<["-"], "dependency-dot">, Flags<[CC1Option]>, HelpText<"Filename to write DOT-formatted header dependencies to">; -def dumpmachine : Flag<"-dumpmachine">; -def dumpspecs : Flag<"-dumpspecs">, Flags<[Unsupported]>; -def dumpversion : Flag<"-dumpversion">; -def dylib__file : Separate<"-dylib_file">; -def dylinker__install__name : JoinedOrSeparate<"-dylinker_install_name">; -def dylinker : Flag<"-dylinker">; -def dynamiclib : Flag<"-dynamiclib">; -def dynamic : Flag<"-dynamic">, Flags<[NoArgumentUnused]>; -def d_Flag : Flag<"-d">, Group<d_Group>; -def d_Joined : Joined<"-d">, Group<d_Group>; -def emit_ast : Flag<"-emit-ast">, +def dumpmachine : Flag<["-"], "dumpmachine">; +def dumpspecs : Flag<["-"], "dumpspecs">, Flags<[Unsupported]>; +def dumpversion : Flag<["-"], "dumpversion">; +def dylib__file : Separate<["-"], "dylib_file">; +def dylinker__install__name : JoinedOrSeparate<["-"], "dylinker_install_name">; +def dylinker : Flag<["-"], "dylinker">; +def dynamiclib : Flag<["-"], "dynamiclib">; +def dynamic : Flag<["-"], "dynamic">, Flags<[NoArgumentUnused]>; +def d_Flag : Flag<["-"], "d">, Group<d_Group>; +def d_Joined : Joined<["-"], "d">, Group<d_Group>; +def emit_ast : Flag<["-"], "emit-ast">, HelpText<"Emit Clang AST files for source inputs">; -def emit_llvm : Flag<"-emit-llvm">, Flags<[CC1Option]>, Group<Action_Group>, +def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option]>, Group<Action_Group>, HelpText<"Use the LLVM representation for assembler and object files">; -def exported__symbols__list : Separate<"-exported_symbols_list">; -def e : JoinedOrSeparate<"-e">; -def fPIC : Flag<"-fPIC">, Group<f_Group>; -def fno_PIC : Flag<"-fno-PIC">, Group<f_Group>; -def fPIE : Flag<"-fPIE">, Group<f_Group>; -def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>; -def faccess_control : Flag<"-faccess-control">, Group<f_Group>; -def fallow_unsupported : Flag<"-fallow-unsupported">, Group<f_Group>; -def faltivec : Flag<"-faltivec">, Group<f_Group>, Flags<[CC1Option]>, +def exported__symbols__list : Separate<["-"], "exported_symbols_list">; +def e : JoinedOrSeparate<["-"], "e">; +def fPIC : Flag<["-"], "fPIC">, Group<f_Group>; +def fno_PIC : Flag<["-"], "fno-PIC">, Group<f_Group>; +def fPIE : Flag<["-"], "fPIE">, Group<f_Group>; +def fno_PIE : Flag<["-"], "fno-PIE">, Group<f_Group>; +def faccess_control : Flag<["-"], "faccess-control">, Group<f_Group>; +def fallow_unsupported : Flag<["-"], "fallow-unsupported">, Group<f_Group>; +def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable AltiVec vector initializer syntax">; -def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>, Flags<[CC1Option]>, +def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use Apple's kernel extensions ABI">; -def fapple_pragma_pack : Flag<"-fapple-pragma-pack">, Group<f_Group>, Flags<[CC1Option]>, +def fapple_pragma_pack : Flag<["-"], "fapple-pragma-pack">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable Apple gcc-compatible #pragma pack handling">; -def faddress_sanitizer : Flag<"-faddress-sanitizer">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Enable AddressSanitizer instrumentation (memory error detection)">; -def fno_address_sanitizer : Flag<"-fno-address-sanitizer">, Group<f_Group>, Flags<[CC1Option]>; -def fthread_sanitizer : Flag<"-fthread-sanitizer">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Enable ThreadSanitizer instrumentation (race detection)">; -def fno_thread_sanitizer : Flag<"-fno-thread-sanitizer">, Group<f_Group>, Flags<[CC1Option]>; -def fasm : Flag<"-fasm">, Group<f_Group>; +def faddress_sanitizer : Flag<["-"], "faddress-sanitizer">, Group<f_Group>; +def fno_address_sanitizer : Flag<["-"], "fno-address-sanitizer">, Group<f_Group>; +def fthread_sanitizer : Flag<["-"], "fthread-sanitizer">, Group<f_Group>; +def fno_thread_sanitizer : Flag<["-"], "fno-thread-sanitizer">, Group<f_Group>; +def fasm : Flag<["-"], "fasm">, Group<f_Group>; -def fasm_blocks : Flag<"-fasm-blocks">, Group<f_Group>; -def fno_asm_blocks : Flag<"-fno-asm-blocks">, Group<f_Group>; +def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>; +def fno_asm_blocks : Flag<["-"], "fno-asm-blocks">, Group<f_Group>; -def fassume_sane_operator_new : Flag<"-fassume-sane-operator-new">, Group<f_Group>; -def fastcp : Flag<"-fastcp">, Group<f_Group>; -def fastf : Flag<"-fastf">, Group<f_Group>; -def fast : Flag<"-fast">, Group<f_Group>; -def fasynchronous_unwind_tables : Flag<"-fasynchronous-unwind-tables">, Group<f_Group>; -def fblocks : Flag<"-fblocks">, Group<f_Group>, Flags<[CC1Option]>, +def fassume_sane_operator_new : Flag<["-"], "fassume-sane-operator-new">, Group<f_Group>; +def fastcp : Flag<["-"], "fastcp">, Group<f_Group>; +def fastf : Flag<["-"], "fastf">, Group<f_Group>; +def fast : Flag<["-"], "fast">, Group<f_Group>; +def fasynchronous_unwind_tables : Flag<["-"], "fasynchronous-unwind-tables">, Group<f_Group>; +def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable the 'blocks' language feature">; -def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>; -def fborland_extensions : Flag<"-fborland-extensions">, Group<f_Group>, Flags<[CC1Option]>, +def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>; +def fborland_extensions : Flag<["-"], "fborland-extensions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Accept non-standard constructs supported by the Borland compiler">; -def fbounds_checking : Flag<"-fbounds-checking">, Group<f_Group>, - HelpText<"Enable run-time bounds checks.">; -def fbounds_checking_EQ : Joined<"-fbounds-checking=">, Flags<[CC1Option]>, +def fbounds_checking : Flag<["-"], "fbounds-checking">, Group<f_Group>, + HelpText<"Enable run-time bounds checks">; +def fbounds_checking_EQ : Joined<["-"], "fbounds-checking=">, Flags<[CC1Option]>, Group<f_Group>; -def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>; -def fbuiltin_strcpy : Flag<"-fbuiltin-strcpy">, Group<f_Group>; -def fbuiltin : Flag<"-fbuiltin">, Group<f_Group>; -def fcaret_diagnostics : Flag<"-fcaret-diagnostics">, Group<f_Group>; -def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">, Flags<[CC1Option]>, - Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior.">; -def fclasspath_EQ : Joined<"-fclasspath=">, Group<f_Group>; -def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, Group<f_Group>, Flags<[CC1Option]>, +def fbuiltin_strcat : Flag<["-"], "fbuiltin-strcat">, Group<f_Group>; +def fbuiltin_strcpy : Flag<["-"], "fbuiltin-strcpy">, Group<f_Group>; +def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>; +def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>; +def fcatch_undefined_behavior : Flag<["-"], "fcatch-undefined-behavior">, Group<f_Group>; +def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>; +def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use colors in diagnostics">; -def fcommon : Flag<"-fcommon">, Group<f_Group>; -def fcompile_resource_EQ : Joined<"-fcompile-resource=">, Group<f_Group>; -def fconstant_cfstrings : Flag<"-fconstant-cfstrings">, Group<f_Group>; -def fconstant_string_class_EQ : Joined<"-fconstant-string-class=">, Group<f_Group>; -def fconstexpr_depth_EQ : Joined<"-fconstexpr-depth=">, Group<f_Group>; -def fconstexpr_backtrace_limit_EQ : Joined<"-fconstexpr-backtrace-limit=">, +def fcommon : Flag<["-"], "fcommon">, Group<f_Group>; +def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>; +def fconstant_cfstrings : Flag<["-"], "fconstant-cfstrings">, Group<f_Group>; +def fconstant_string_class_EQ : Joined<["-"], "fconstant-string-class=">, Group<f_Group>; +def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>; +def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">, Group<f_Group>; -def fno_crash_diagnostics : Flag<"-fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>; -def fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>; -def fcxx_exceptions: Flag<"-fcxx-exceptions">, Group<f_Group>, +def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>; +def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>; +def fcxx_exceptions: Flag<["-"], "fcxx-exceptions">, Group<f_Group>, HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>; -def fcxx_modules : Flag <"-fcxx-modules">, Group<f_Group>, Flags<[NoForward]>; -def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>; -def fdebug_pass_structure : Flag<"-fdebug-pass-structure">, Group<f_Group>; -def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_clang_Group>; -def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, Group<f_clang_Group>, +def fcxx_modules : Flag <["-"], "fcxx-modules">, Group<f_Group>, Flags<[NoForward]>; +def fdebug_pass_arguments : Flag<["-"], "fdebug-pass-arguments">, Group<f_Group>; +def fdebug_pass_structure : Flag<["-"], "fdebug-pass-structure">, Group<f_Group>; +def fdiagnostics_fixit_info : Flag<["-"], "fdiagnostics-fixit-info">, Group<f_clang_Group>; +def fdiagnostics_parseable_fixits : Flag<["-"], "fdiagnostics-parseable-fixits">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Print fix-its in machine parseable form">; -def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, +def fdiagnostics_print_source_range_info : Flag<["-"], "fdiagnostics-print-source-range-info">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Print source range spans in numeric form">; -def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>, +def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Print option name with mappable diagnostics">; -def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">, Group<f_Group>, +def fdiagnostics_show_name : Flag<["-"], "fdiagnostics-show-name">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Print diagnostic name">; -def fdiagnostics_show_note_include_stack : Flag<"-fdiagnostics-show-note-include-stack">, +def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">; -def fdiagnostics_format_EQ : Joined<"-fdiagnostics-format=">, Group<f_clang_Group>; -def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, Group<f_clang_Group>; -def fdiagnostics_show_template_tree : Flag<"-fdiagnostics-show-template-tree">, +def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group<f_clang_Group>; +def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group<f_clang_Group>; +def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Print a template comparison tree for differing templates">; -def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>, +def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group<f_Group>, HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>; -def fdwarf2_cfi_asm : Flag<"-fdwarf2-cfi-asm">, Group<f_Group>; -def fno_dwarf2_cfi_asm : Flag<"-fno-dwarf2-cfi-asm">, Group<f_Group>, Flags<[CC1Option]>; -def fdwarf_directory_asm : Flag<"-fdwarf-directory-asm">, Group<f_Group>; -def fno_dwarf_directory_asm : Flag<"-fno-dwarf-directory-asm">, Group<f_Group>, Flags<[CC1Option]>; -def felide_constructors : Flag<"-felide-constructors">, Group<f_Group>; -def fno_elide_type : Flag<"-fno-elide-type">, Group<f_Group>, +def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<f_Group>; +def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group<f_Group>, Flags<[CC1Option]>; +def fdwarf_directory_asm : Flag<["-"], "fdwarf-directory-asm">, Group<f_Group>; +def fno_dwarf_directory_asm : Flag<["-"], "fno-dwarf-directory-asm">, Group<f_Group>, Flags<[CC1Option]>; +def felide_constructors : Flag<["-"], "felide-constructors">, Group<f_Group>; +def fno_elide_type : Flag<["-"], "fno-elide-type">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not elide types when printing diagnostics">; -def feliminate_unused_debug_symbols : Flag<"-feliminate-unused-debug-symbols">, Group<f_Group>; -def femit_all_decls : Flag<"-femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>, +def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group<f_Group>; +def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Emit all declarations, even if unused">; -def fencoding_EQ : Joined<"-fencoding=">, Group<f_Group>; -def ferror_limit_EQ : Joined<"-ferror-limit=">, Group<f_Group>; -def fexceptions : Flag<"-fexceptions">, Group<f_Group>, Flags<[CC1Option]>, +def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>; +def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>; +def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable support for exception handling">; -def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>; -def fhosted : Flag<"-fhosted">, Group<f_Group>; -def ffast_math : Flag<"-ffast-math">, Group<f_Group>, Flags<[CC1Option]>, +def fextdirs_EQ : Joined<["-"], "fextdirs=">, Group<f_Group>; +def fhosted : Flag<["-"], "fhosted">, Group<f_Group>; +def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable the *frontend*'s 'fast-math' mode. This has no effect on " "optimizations, but provides a preprocessor macro __FAST_MATH__ the " - "same as GCC's -ffast-math flag.">; -def fmath_errno : Flag<"-fmath-errno">, Group<f_Group>, Flags<[CC1Option]>, + "same as GCC's -ffast-math flag">; +def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>; +def fmath_errno : Flag<["-"], "fmath-errno">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Require math functions to indicate errors by setting errno">; -def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>; -def fsignaling_math : Flag<"-fsignaling-math">, Group<f_Group>; -def fno_signaling_math : Flag<"-fno-signaling-math">, Group<f_Group>; -def funsafe_math_optimizations : Flag<"-funsafe-math-optimizations">, +def fno_math_errno : Flag<["-"], "fno-math-errno">, Group<f_Group>; +def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>; +def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>; +def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>, + Flags<[CC1Option]>, MetaVarName<"<check>">, + HelpText<"Enable runtime instrumentation for bug detection: " + "address (memory errors) | thread (race detection) | " + "undefined (miscellaneous undefined behavior)">; +def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>; +def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">, Group<f_Group>; -def fno_unsafe_math_optimizations : Flag<"-fno-unsafe-math-optimizations">, +def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">, Group<f_Group>; -def fassociative_math : Flag<"-fassociative-math">, Group<f_Group>; -def fno_associative_math : Flag<"-fno-associative-math">, Group<f_Group>; -def freciprocal_math : Flag<"-freciprocal-math">, Group<f_Group>; -def fno_reciprocal_math : Flag<"-fno-reciprocal-math">, Group<f_Group>; -def ffinite_math_only : Flag<"-ffinite-math-only">, Group<f_Group>, Flags<[CC1Option]>; -def fno_finite_math_only : Flag<"-fno-finite-math-only">, Group<f_Group>; -def fsigned_zeros : Flag<"-fsigned-zeros">, Group<f_Group>; -def fno_signed_zeros : Flag<"-fno-signed-zeros">, Group<f_Group>; -def fhonor_nans : Flag<"-fhonor-nans">, Group<f_Group>; -def fno_honor_nans : Flag<"-fno-honor-nans">, Group<f_Group>; -def fhonor_infinities : Flag<"-fhonor-infinities">, Group<f_Group>; -def fno_honor_infinities : Flag<"-fno-honor-infinities">, Group<f_Group>; +def fassociative_math : Flag<["-"], "fassociative-math">, Group<f_Group>; +def fno_associative_math : Flag<["-"], "fno-associative-math">, Group<f_Group>; +def freciprocal_math : Flag<["-"], "freciprocal-math">, Group<f_Group>; +def fno_reciprocal_math : Flag<["-"], "fno-reciprocal-math">, Group<f_Group>; +def ffinite_math_only : Flag<["-"], "ffinite-math-only">, Group<f_Group>, Flags<[CC1Option]>; +def fno_finite_math_only : Flag<["-"], "fno-finite-math-only">, Group<f_Group>; +def fsigned_zeros : Flag<["-"], "fsigned-zeros">, Group<f_Group>; +def fno_signed_zeros : Flag<["-"], "fno-signed-zeros">, Group<f_Group>; +def fhonor_nans : Flag<["-"], "fhonor-nans">, Group<f_Group>; +def fno_honor_nans : Flag<["-"], "fno-honor-nans">, Group<f_Group>; +def fhonor_infinities : Flag<["-"], "fhonor-infinities">, Group<f_Group>; +def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">, Group<f_Group>; // Sic. This option was misspelled originally. -def fhonor_infinites : Flag<"-fhonor-infinites">, Alias<fhonor_infinities>; -def fno_honor_infinites : Flag<"-fno-honor-infinites">, Alias<fno_honor_infinities>; -def ftrapping_math : Flag<"-ftrapping-math">, Group<f_Group>; -def fno_trapping_math : Flag<"-fno-trapping-math">, Group<f_Group>; -def ffp_contract : Joined<"-ffp-contract=">, Group<f_Group>, +def fhonor_infinites : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>; +def fno_honor_infinites : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>; +def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>; +def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>; +def ffp_contract : Joined<["-"], "ffp-contract=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Form fused FP ops (e.g. FMAs): fast (everywhere)" " | on (according to FP_CONTRACT pragma, default) | off (never fuse)">; -def ffor_scope : Flag<"-ffor-scope">, Group<f_Group>; -def fno_for_scope : Flag<"-fno-for-scope">, Group<f_Group>; +def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>; +def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>; -def frewrite_includes : Flag<"-frewrite-includes">, Group<f_Group>, +def frewrite_includes : Flag<["-"], "frewrite-includes">, Group<f_Group>, Flags<[CC1Option]>; -def fno_rewrite_includes : Flag<"-fno-rewrite-includes">, Group<f_Group>; +def fno_rewrite_includes : Flag<["-"], "fno-rewrite-includes">, Group<f_Group>; -def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>, Flags<[CC1Option]>, +def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Assert that the compilation takes place in a freestanding environment">; -def fformat_extensions: Flag<"-fformat-extensions">, Group<f_Group>, Flags<[CC1Option]>, +def fformat_extensions: Flag<["-"], "fformat-extensions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable FreeBSD kernel specific format string extensions">; -def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>, +def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Allow GNU-extension keywords regardless of language standard">; -def fgnu89_inline : Flag<"-fgnu89-inline">, Group<f_Group>, Flags<[CC1Option]>, +def fgnu89_inline : Flag<["-"], "fgnu89-inline">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use the gnu89 inline semantics">; -def fno_gnu89_inline : Flag<"-fno-gnu89-inline">, Group<f_Group>; -def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>, +def fno_gnu89_inline : Flag<["-"], "fno-gnu89-inline">, Group<f_Group>; +def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>, HelpText<"Generate output compatible with the standard GNU Objective-C runtime">; -def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">, Flags<[CC1Option]>; -def filelist : Separate<"-filelist">, Flags<[LinkerInput]>; -def findirect_virtual_calls : Flag<"-findirect-virtual-calls">, Alias<fapple_kext>; -def finline_functions : Flag<"-finline-functions">, Group<clang_ignored_f_Group>; -def finline : Flag<"-finline">, Group<clang_ignored_f_Group>; -def finstrument_functions : Flag<"-finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>, +def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>; +def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>; +def findirect_virtual_calls : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>; +def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_f_Group>; +def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>; +def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Generate calls to instrument function entry and exit">; -def fkeep_inline_functions : Flag<"-fkeep-inline-functions">, Group<clang_ignored_f_Group>; -def flat__namespace : Flag<"-flat_namespace">; -def flax_vector_conversions : Flag<"-flax-vector-conversions">, Group<f_Group>; -def flimit_debug_info : Flag<"-flimit-debug-info">, Group<f_Group>, Flags<[CC1Option]>, +def fkeep_inline_functions : Flag<["-"], "fkeep-inline-functions">, Group<clang_ignored_f_Group>; +def flat__namespace : Flag<["-"], "flat_namespace">; +def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>; +def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Limit debug information produced to reduce size of debug binary">; -def flimited_precision_EQ : Joined<"-flimited-precision=">, Group<f_Group>; -def flto : Flag<"-flto">, Group<f_Group>; -def fno_lto : Flag<"-fno-lto">, Group<f_Group>; -def fmacro_backtrace_limit_EQ : Joined<"-fmacro-backtrace-limit=">, +def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>; +def flto : Flag<["-"], "flto">, Group<f_Group>; +def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>; +def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">, 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>, Flags<[CC1Option]>, +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>, Flags<[CC1Option]>, HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">; -def fenable_experimental_ms_inline_asm : Flag<"-fenable-experimental-ms-inline-asm">, Group<f_Group>, Flags<[CC1Option]>, +def fenable_experimental_ms_inline_asm : Flag<["-"], "fenable-experimental-ms-inline-asm">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable support for Microsoft style inine assembly">; -def fms_compatibility : Flag<"-fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>, +def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable Microsoft compatibility mode">; -def fmsc_version : Joined<"-fmsc-version=">, Group<f_Group>, Flags<[CC1Option]>, +def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Version of the Microsoft C/C++ compiler to report in _MSC_VER (0 = don't define it (default))">; -def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">, Group<f_Group>, +def fdelayed_template_parsing : Flag<["-"], "fdelayed-template-parsing">, Group<f_Group>, HelpText<"Parse templated function definitions at the end of the " "translation unit ">, Flags<[CC1Option]>; -def fmodule_cache_path : Separate<"-fmodule-cache-path">, Group<i_Group>, +def fmodule_cache_path : Separate<["-"], "fmodule-cache-path">, Group<i_Group>, Flags<[NoForward,CC1Option]>, MetaVarName<"<directory>">, HelpText<"Specify the module cache path">; -def fmodules : Flag <"-fmodules">, Group<f_Group>, Flags<[NoForward,CC1Option]>, +def fmodules : Flag <["-"], "fmodules">, Group<f_Group>, Flags<[NoForward,CC1Option]>, HelpText<"Enable the 'modules' language feature">; - -def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>; -def fmudflap : Flag<"-fmudflap">, Group<f_Group>; -def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>; -def fnext_runtime : Flag<"-fnext-runtime">, Group<f_Group>; -def fno_access_control : Flag<"-fno-access-control">, Group<f_Group>, Flags<[CC1Option]>, +def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>; + +def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>; +def fmudflap : Flag<["-"], "fmudflap">, Group<f_Group>; +def fnested_functions : Flag<["-"], "fnested-functions">, Group<f_Group>; +def fnext_runtime : Flag<["-"], "fnext-runtime">, Group<f_Group>; +def fno_access_control : Flag<["-"], "fno-access-control">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disable C++ access control">; -def fno_apple_pragma_pack : Flag<"-fno-apple-pragma-pack">, Group<f_Group>; -def fno_asm : Flag<"-fno-asm">, Group<f_Group>; -def fno_asynchronous_unwind_tables : Flag<"-fno-asynchronous-unwind-tables">, Group<f_Group>; -def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">, Group<f_Group>, +def fno_apple_pragma_pack : Flag<["-"], "fno-apple-pragma-pack">, Group<f_Group>; +def fno_asm : Flag<["-"], "fno-asm">, Group<f_Group>; +def fno_asynchronous_unwind_tables : Flag<["-"], "fno-asynchronous-unwind-tables">, Group<f_Group>; +def fno_assume_sane_operator_new : Flag<["-"], "fno-assume-sane-operator-new">, Group<f_Group>, HelpText<"Don't assume that C++'s global operator new can't alias any pointer">, Flags<[CC1Option]>; -def fno_blocks : Flag<"-fno-blocks">, Group<f_Group>; -def fno_borland_extensions : Flag<"-fno-borland-extensions">, Group<f_Group>; -def fno_builtin_strcat : Flag<"-fno-builtin-strcat">, Group<f_Group>; -def fno_builtin_strcpy : Flag<"-fno-builtin-strcpy">, Group<f_Group>; -def fno_builtin : Flag<"-fno-builtin">, Group<f_Group>, Flags<[CC1Option]>, +def fno_blocks : Flag<["-"], "fno-blocks">, Group<f_Group>; +def fno_borland_extensions : Flag<["-"], "fno-borland-extensions">, Group<f_Group>; +def fno_builtin_strcat : Flag<["-"], "fno-builtin-strcat">, Group<f_Group>; +def fno_builtin_strcpy : Flag<["-"], "fno-builtin-strcpy">, Group<f_Group>; +def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disable implicit builtin knowledge of functions">; -def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">, Group<f_Group>, +def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<f_Group>, Flags<[CC1Option]>; -def fno_color_diagnostics : Flag<"-fno-color-diagnostics">, Group<f_Group>; -def fno_common : Flag<"-fno-common">, Group<f_Group>, Flags<[CC1Option]>, +def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<f_Group>; +def fno_common : Flag<["-"], "fno-common">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Compile common globals like normal definitions">; -def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">, Group<f_Group>, +def fno_constant_cfstrings : Flag<["-"], "fno-constant-cfstrings">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disable creation of CodeFoundation-type constant strings">; -def fno_cxx_exceptions: Flag<"-fno-cxx-exceptions">, Group<f_Group>; -def fno_cxx_modules : Flag <"-fno-cxx-modules">, Group<f_Group>, Flags<[NoForward]>; -def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">, Group<f_Group>, +def fno_cxx_exceptions: Flag<["-"], "fno-cxx-exceptions">, Group<f_Group>; +def fno_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group<f_Group>, Flags<[NoForward]>; +def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">; -def fno_diagnostics_show_name : Flag<"-fno-diagnostics-show-name">, Group<f_Group>; -def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_Group>; -def fno_diagnostics_show_note_include_stack : Flag<"-fno-diagnostics-show-note-include-stack">, +def fno_diagnostics_show_name : Flag<["-"], "fno-diagnostics-show-name">, Group<f_Group>; +def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>; +def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">, Flags<[CC1Option]>, Group<f_Group>, HelpText<"Display include stacks for diagnostic notes">; -def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>, +def fno_dollars_in_identifiers : Flag<["-"], "fno-dollars-in-identifiers">, Group<f_Group>, HelpText<"Disallow '$' in identifiers">, Flags<[CC1Option]>; -def fno_elide_constructors : Flag<"-fno-elide-constructors">, Group<f_Group>, +def fno_elide_constructors : Flag<["-"], "fno-elide-constructors">, Group<f_Group>, HelpText<"Disable C++ copy constructor elision">, Flags<[CC1Option]>; -def fno_eliminate_unused_debug_symbols : Flag<"-fno-eliminate-unused-debug-symbols">, Group<f_Group>; -def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>; -def fno_gnu_keywords : Flag<"-fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>; -def fno_inline_functions : Flag<"-fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>; -def fno_inline : Flag<"-fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>; -def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>; -def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, Group<f_Group>, +def fno_eliminate_unused_debug_symbols : Flag<["-"], "fno-eliminate-unused-debug-symbols">, Group<f_Group>; +def fno_exceptions : Flag<["-"], "fno-exceptions">, Group<f_Group>; +def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>; +def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>; +def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>; +def fno_keep_inline_functions : Flag<["-"], "fno-keep-inline-functions">, Group<clang_ignored_f_Group>; +def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>, HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">, Flags<[CC1Option]>; -def fno_limit_debug_info : Flag<"-fno-limit-debug-info">, Group<f_Group>, Flags<[CC1Option]>, +def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not limit debug information produced to reduce size of debug binary">; -def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>, - Flags<[CC1Option]>, HelpText<"Disallow merging of constants.">; -def fno_modules : Flag <"-fno-modules">, Group<f_Group>, Flags<[NoForward]>; -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_exceptions: Flag<"-fno-objc-exceptions">, Group<f_Group>; -def fno_objc_legacy_dispatch : Flag<"-fno-objc-legacy-dispatch">, Group<f_Group>; -def fno_omit_frame_pointer : Flag<"-fno-omit-frame-pointer">, Group<f_Group>; -def fno_operator_names : Flag<"-fno-operator-names">, Group<f_Group>, +def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>, + Flags<[CC1Option]>, HelpText<"Disallow merging of constants">; +def fno_modules : Flag <["-"], "fno-modules">, Group<f_Group>, Flags<[NoForward]>; +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_exceptions: Flag<["-"], "fno-objc-exceptions">, Group<f_Group>; +def fno_objc_legacy_dispatch : Flag<["-"], "fno-objc-legacy-dispatch">, Group<f_Group>; +def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>; +def fno_operator_names : Flag<["-"], "fno-operator-names">, Group<f_Group>, HelpText<"Do not treat C++ operator name keywords as synonyms for operators">, Flags<[CC1Option]>; -def fno_pascal_strings : Flag<"-fno-pascal-strings">, Group<f_Group>; -def fno_rtti : Flag<"-fno-rtti">, Group<f_Group>, Flags<[CC1Option]>, +def fno_pascal_strings : Flag<["-"], "fno-pascal-strings">, Group<f_Group>; +def fno_rtti : Flag<["-"], "fno-rtti">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disable generation of rtti information">; -def fno_short_enums : Flag<"-fno-short-enums">, Group<f_Group>; -def fno_show_column : Flag<"-fno-show-column">, Group<f_Group>, Flags<[CC1Option]>, +def fno_short_enums : Flag<["-"], "fno-short-enums">, Group<f_Group>; +def fno_show_column : Flag<["-"], "fno-show-column">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not include column number on diagnostics">; -def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>, +def fno_show_source_location : Flag<["-"], "fno-show-source-location">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not include source location information with diagnostics">; -def fno_spell_checking : Flag<"-fno-spell-checking">, Group<f_Group>, +def fno_spell_checking : Flag<["-"], "fno-spell-checking">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disable spell-checking">; -def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>; -def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<f_Group>; -def fno_strict_enums : Flag<"-fno-strict-enums">, Group<f_Group>; -def fno_strict_overflow : Flag<"-fno-strict-overflow">, Group<f_Group>; -def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>, +def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>; +def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>; +def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>; +def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>; +def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not emit code to make initialization of local statics thread safe">; -def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">, Group<f_Group>, Flags<[CC1Option]>, +def fno_use_cxa_atexit : Flag<["-"], "fno-use-cxa-atexit">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Don't use __cxa_atexit for calling destructors">; -def fno_unit_at_a_time : Flag<"-fno-unit-at-a-time">, Group<f_Group>; -def fno_unwind_tables : Flag<"-fno-unwind-tables">, Group<f_Group>; -def fno_verbose_asm : Flag<"-fno-verbose-asm">, Group<f_Group>; -def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>; -def fno_wrapv : Flag<"-fno-wrapv">, Group<f_Group>; -def fno_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>; -def fobjc_arc : Flag<"-fobjc-arc">, Group<f_Group>, Flags<[CC1Option]>, +def fno_unit_at_a_time : Flag<["-"], "fno-unit-at-a-time">, Group<f_Group>; +def fno_unwind_tables : Flag<["-"], "fno-unwind-tables">, Group<f_Group>; +def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>; +def fno_working_directory : Flag<["-"], "fno-working-directory">, Group<f_Group>; +def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>; +def fno_zero_initialized_in_bss : Flag<["-"], "fno-zero-initialized-in-bss">, Group<f_Group>; +def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Synthesize retain and release calls for Objective-C pointers">; -def fno_objc_arc : Flag<"-fno-objc-arc">, Group<f_Group>; -def fobjc_arc_exceptions : Flag<"-fobjc-arc-exceptions">, Group<f_Group>, Flags<[CC1Option]>, +def fno_objc_arc : Flag<["-"], "fno-objc-arc">, Group<f_Group>; +def fobjc_arc_exceptions : Flag<["-"], "fobjc-arc-exceptions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use EH-safe code when synthesizing retains and releases in -fobjc-arc">; -def fno_objc_arc_exceptions : Flag<"-fno-objc-arc-exceptions">, Group<f_Group>; -def fobjc_atdefs : Flag<"-fobjc-atdefs">, Group<clang_ignored_f_Group>; -def fobjc_call_cxx_cdtors : Flag<"-fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>; -def fobjc_exceptions: Flag<"-fobjc-exceptions">, Group<f_Group>, +def fno_objc_arc_exceptions : Flag<["-"], "fno-objc-arc-exceptions">, Group<f_Group>; +def fobjc_atdefs : Flag<["-"], "fobjc-atdefs">, Group<clang_ignored_f_Group>; +def fobjc_call_cxx_cdtors : Flag<["-"], "fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>; +def fobjc_exceptions: Flag<["-"], "fobjc-exceptions">, Group<f_Group>, HelpText<"Enable Objective-C exceptions">, Flags<[CC1Option]>; -def fobjc_gc_only : Flag<"-fobjc-gc-only">, Group<f_Group>, Flags<[CC1Option]>, +def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use GC exclusively for Objective-C related memory management">; -def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>, Flags<[CC1Option]>, +def fobjc_gc : Flag<["-"], "fobjc-gc">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable Objective-C garbage collection">; -def fobjc_legacy_dispatch : Flag<"-fobjc-legacy-dispatch">, Group<f_Group>; -def fobjc_new_property : Flag<"-fobjc-new-property">, Group<clang_ignored_f_Group>; -def fobjc_infer_related_result_type : Flag<"-fobjc-infer-related-result-type">, +def fobjc_legacy_dispatch : Flag<["-"], "fobjc-legacy-dispatch">, Group<f_Group>; +def fobjc_new_property : Flag<["-"], "fobjc-new-property">, Group<clang_ignored_f_Group>; +def fobjc_infer_related_result_type : Flag<["-"], "fobjc-infer-related-result-type">, Group<f_Group>; -def fno_objc_infer_related_result_type : Flag< - "-fno-objc-infer-related-result-type">, Group<f_Group>, +def fno_objc_infer_related_result_type : Flag<["-"], + "fno-objc-infer-related-result-type">, Group<f_Group>, HelpText< "do not infer Objective-C related result type based on method family">, Flags<[CC1Option]>; -def fobjc_link_runtime: Flag<"-fobjc-link-runtime">, Group<f_Group>; +def fobjc_link_runtime: Flag<["-"], "fobjc-link-runtime">, Group<f_Group>; // Objective-C ABI options. -def fobjc_runtime_EQ : Joined<"-fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option]>, +def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Specify the target Objective-C runtime kind and version">; -def fobjc_abi_version_EQ : Joined<"-fobjc-abi-version=">, Group<f_Group>; -def fobjc_nonfragile_abi_version_EQ : Joined<"-fobjc-nonfragile-abi-version=">, Group<f_Group>; -def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, Group<f_Group>; -def fno_objc_nonfragile_abi : Flag<"-fno-objc-nonfragile-abi">, Group<f_Group>; +def fobjc_abi_version_EQ : Joined<["-"], "fobjc-abi-version=">, Group<f_Group>; +def fobjc_nonfragile_abi_version_EQ : Joined<["-"], "fobjc-nonfragile-abi-version=">, Group<f_Group>; +def fobjc_nonfragile_abi : Flag<["-"], "fobjc-nonfragile-abi">, Group<f_Group>; +def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Group>; -def fobjc_sender_dependent_dispatch : Flag<"-fobjc-sender-dependent-dispatch">, Group<f_Group>; -def fobjc : Flag<"-fobjc">, Group<f_Group>; -def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>; -def fopenmp : Flag<"-fopenmp">, Group<f_Group>; -def fno_optimize_sibling_calls : Flag<"-fno-optimize-sibling-calls">, Group<f_Group>; -def foptimize_sibling_calls : Flag<"-foptimize-sibling-calls">, Group<f_Group>; -def force__cpusubtype__ALL : Flag<"-force_cpusubtype_ALL">; -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>, Flags<[CC1Option]>, +def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>; +def fobjc : Flag<["-"], "fobjc">, Group<f_Group>; +def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>; +def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>; +def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>; +def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>; +def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">; +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>, Flags<[CC1Option]>, HelpText<"Specify the default maximum struct packing alignment">; -def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>, Flags<[CC1Option]>, +def fpascal_strings : Flag<["-"], "fpascal-strings">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Recognize and construct Pascal-style string literals">; -def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>; -def fpic : Flag<"-fpic">, Group<f_Group>; -def fno_pic : Flag<"-fno-pic">, Group<f_Group>; -def fpie : Flag<"-fpie">, Group<f_Group>; -def fno_pie : Flag<"-fno-pie">, Group<f_Group>; -def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>; -def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>; -def framework : Separate<"-framework">, Flags<[LinkerInput]>; -def frandom_seed_EQ : Joined<"-frandom-seed=">, Group<clang_ignored_f_Group>; -def frtti : Flag<"-frtti">, Group<f_Group>; -def fsched_interblock : Flag<"-fsched-interblock">, Group<clang_ignored_f_Group>; -def fshort_enums : Flag<"-fshort-enums">, Group<f_Group>, Flags<[CC1Option]>, +def fpch_preprocess : Flag<["-"], "fpch-preprocess">, Group<f_Group>; +def fpic : Flag<["-"], "fpic">, Group<f_Group>; +def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>; +def fpie : Flag<["-"], "fpie">, Group<f_Group>; +def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>; +def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group<f_Group>; +def fprofile_generate : Flag<["-"], "fprofile-generate">, Group<f_Group>; +def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>; +def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group<clang_ignored_f_Group>; +def frtti : Flag<["-"], "frtti">, Group<f_Group>; +def fsched_interblock : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>; +def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Allocate to an enum type only as many bytes as it needs for the declared range of possible values">; -def freorder_blocks : Flag<"-freorder-blocks">, Group<clang_ignored_f_Group>; -def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>, Flags<[CC1Option]>, +def freorder_blocks : Flag<["-"], "freorder-blocks">, Group<clang_ignored_f_Group>; +def fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Force wchar_t to be a short unsigned int">; -def fshow_overloads_EQ : Joined<"-fshow-overloads=">, Group<f_Group>, Flags<[CC1Option]>, +def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Which overload candidates to show when overload resolution fails: " "best|all; defaults to all">; -def fshow_column : Flag<"-fshow-column">, Group<f_Group>, Flags<[CC1Option]>; -def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>; -def fspell_checking : Flag<"-fspell-checking">, Group<f_Group>; -def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>; -def fsigned_char : Flag<"-fsigned-char">, Group<f_Group>; -def fstack_protector_all : Flag<"-fstack-protector-all">, Group<f_Group>; -def fstack_protector : Flag<"-fstack-protector">, Group<f_Group>; -def fstrict_aliasing : Flag<"-fstrict-aliasing">, Group<f_Group>; -def fstrict_enums : Flag<"-fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>, +def fshow_column : Flag<["-"], "fshow-column">, Group<f_Group>, Flags<[CC1Option]>; +def fshow_source_location : Flag<["-"], "fshow-source-location">, Group<f_Group>; +def fspell_checking : Flag<["-"], "fspell-checking">, Group<f_Group>; +def fsigned_bitfields : Flag<["-"], "fsigned-bitfields">, Group<f_Group>; +def fsigned_char : Flag<["-"], "fsigned-char">, Group<f_Group>; +def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>; +def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>; +def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>; +def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable optimizations based on the strict definition of an enum's " - "value range.">; -def fstrict_overflow : Flag<"-fstrict-overflow">, Group<f_Group>; -def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>; -def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>; -def ftemplate_depth_EQ : Joined<"-ftemplate-depth=">, Group<f_Group>; -def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>; -def ftemplate_backtrace_limit_EQ : Joined<"-ftemplate-backtrace-limit=">, + "value range">; +def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>; +def fsyntax_only : Flag<["-"], "fsyntax-only">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>; +def ftabstop_EQ : Joined<["-"], "ftabstop=">, Group<f_Group>; +def ftemplate_depth_EQ : Joined<["-"], "ftemplate-depth=">, Group<f_Group>; +def ftemplate_depth_ : Joined<["-"], "ftemplate-depth-">, Group<f_Group>; +def ftemplate_backtrace_limit_EQ : Joined<["-"], "ftemplate-backtrace-limit=">, Group<f_Group>; -def ftest_coverage : Flag<"-ftest-coverage">, Group<f_Group>; -def Wlarge_by_value_copy_def : Flag<"-Wlarge-by-value-copy">, +def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>; +def Wlarge_by_value_copy_def : Flag<["-"], "Wlarge-by-value-copy">, HelpText<"Warn if a function definition returns or accepts an object larger " - "in bytes that a given value">; -def Wlarge_by_value_copy_EQ : Joined<"-Wlarge-by-value-copy=">, Flags<[CC1Option]>; + "in bytes than a given value">, Flags<[HelpHidden]>; +def Wlarge_by_value_copy_EQ : Joined<["-"], "Wlarge-by-value-copy=">, Flags<[CC1Option]>; // Just silence warnings about -Wlarger-than, -Wframe-larger-than for now. -def Wlarger_than : Separate<"-Wlarger-than">, Group<clang_ignored_f_Group>; -def Wlarger_than_EQ : Joined<"-Wlarger-than=">, Alias<Wlarger_than>; -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 Wlarger_than : Separate<["-"], "Wlarger-than">, Group<clang_ignored_f_Group>; +def Wlarger_than_EQ : Joined<["-"], "Wlarger-than=">, Alias<Wlarger_than>; +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">, Alias<fapple_kext>; -def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>; -def ftime_report : Flag<"-ftime-report">, Group<f_Group>, Flags<[CC1Option]>; -def ftlsmodel_EQ : Joined<"-ftls-model=">, Group<f_Group>, Flags<[CC1Option]>; -def ftrapv : Flag<"-ftrapv">, Group<f_Group>, Flags<[CC1Option]>, +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>, Flags<[CC1Option]>; +def ftlsmodel_EQ : Joined<["-"], "ftls-model=">, Group<f_Group>, Flags<[CC1Option]>; +def ftrapv : Flag<["-"], "ftrapv">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Trap on integer overflow">; -def ftrapv_handler_EQ : Joined<"-ftrapv-handler=">, Group<f_Group>, +def ftrapv_handler_EQ : Joined<["-"], "ftrapv-handler=">, Group<f_Group>, MetaVarName<"<function name>">, - HelpText<"Specify the function to be called on overflow.">; -def ftrapv_handler : Separate<"-ftrapv-handler">, Group<f_Group>, Flags<[CC1Option]>; -def ftrap_function_EQ : Joined<"-ftrap-function=">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Specify the function to be called on overflow">; +def ftrapv_handler : Separate<["-"], "ftrapv-handler">, Group<f_Group>, Flags<[CC1Option]>; +def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Issue call to specified function rather than a trap instruction">; -def funit_at_a_time : Flag<"-funit-at-a-time">, Group<f_Group>; -def funroll_loops : Flag<"-funroll-loops">, Group<f_Group>, +def funit_at_a_time : Flag<["-"], "funit-at-a-time">, Group<f_Group>; +def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>, HelpText<"Turn on loop unroller">, Flags<[CC1Option]>; -def funsigned_bitfields : Flag<"-funsigned-bitfields">, Group<f_Group>; -def funsigned_char : Flag<"-funsigned-char">, Group<f_Group>; -def funwind_tables : Flag<"-funwind-tables">, Group<f_Group>; -def fuse_cxa_atexit : Flag<"-fuse-cxa-atexit">, Group<f_Group>; -def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>; -def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>; -def fvisibility_inlines_hidden : Flag<"-fvisibility-inlines-hidden">, Group<f_Group>, +def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>; +def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>; +def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>; +def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group<f_Group>; +def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>; +def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>; +def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Group<f_Group>, HelpText<"Give inline C++ member functions default visibility by default">, Flags<[CC1Option]>; -def fwrapv : Flag<"-fwrapv">, Group<f_Group>, Flags<[CC1Option]>, +def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Treat signed integer overflow as two's complement">; -def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>, +def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Store string literals as writable data">; -def fzero_initialized_in_bss : Flag<"-fzero-initialized-in-bss">, Group<f_Group>; -def ffunction_sections: Flag <"-ffunction-sections">, Group<f_Group>, +def fzero_initialized_in_bss : Flag<["-"], "fzero-initialized-in-bss">, Group<f_Group>; +def ffunction_sections: Flag <["-"], "ffunction-sections">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Place each function in its own section (ELF Only)">; -def fdata_sections : Flag <"-fdata-sections">, Group<f_Group>, Flags<[CC1Option]>, +def fdata_sections : Flag <["-"], "fdata-sections">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Place each data in its own section (ELF Only)">; -def f : Joined<"-f">, Group<f_Group>; -def g_Flag : Flag<"-g">, Group<g_Group>, +def f : Joined<["-"], "f">, Group<f_Group>; +def g_Flag : Flag<["-"], "g">, Group<g_Group>, HelpText<"Generate source level debug information">, Flags<[CC1Option]>; -def gline_tables_only : Flag<"-gline-tables-only">, Group<g_Group>, +def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<g_Group>, HelpText<"Emit debug line number tables only">, Flags<[CC1Option]>; -def g0 : Flag<"-g0">, Group<g_Group>; -def g1 : Flag<"-g1">, Group<g_Group>; -def g2 : Flag<"-g2">, Group<g_Group>; -def g3 : Flag<"-g3">, Group<g_Group>; -def ggdb : Flag<"-ggdb">, Group<g_Group>; -def ggdb0 : Flag<"-ggdb0">, Group<g_Group>; -def ggdb1 : Flag<"-ggdb1">, Group<g_Group>; -def ggdb2 : Flag<"-ggdb2">, Group<g_Group>; -def ggdb3 : Flag<"-ggdb3">, Group<g_Group>; -def gdwarf_2 : Flag<"-gdwarf-2">, Group<g_Group>; -def gdwarf_3 : Flag<"-gdwarf-3">, Group<g_Group>; -def gdwarf_4 : Flag<"-gdwarf-4">, Group<g_Group>; -def gfull : Flag<"-gfull">, Group<g_Group>; -def gused : Flag<"-gused">, Group<g_Group>; -def gstabs : Joined<"-gstabs">, Group<g_Group>, Flags<[Unsupported]>; -def gcoff : Joined<"-gcoff">, Group<g_Group>, Flags<[Unsupported]>; -def gxcoff : Joined<"-gxcoff">, Group<g_Group>, Flags<[Unsupported]>; -def gvms : Joined<"-gvms">, Group<g_Group>, Flags<[Unsupported]>; -def gtoggle : Flag<"-gtoggle">, Group<g_flags_Group>, Flags<[Unsupported]>; -def grecord_gcc_switches : Flag<"-grecord-gcc-switches">, Group<g_flags_Group>; -def gno_record_gcc_switches : Flag<"-gno-record-gcc-switches">, +def g0 : Flag<["-"], "g0">, Group<g_Group>; +def g1 : Flag<["-"], "g1">, Group<g_Group>; +def g2 : Flag<["-"], "g2">, Group<g_Group>; +def g3 : Flag<["-"], "g3">, Group<g_Group>; +def ggdb : Flag<["-"], "ggdb">, Group<g_Group>; +def ggdb0 : Flag<["-"], "ggdb0">, Group<g_Group>; +def ggdb1 : Flag<["-"], "ggdb1">, Group<g_Group>; +def ggdb2 : Flag<["-"], "ggdb2">, Group<g_Group>; +def ggdb3 : Flag<["-"], "ggdb3">, Group<g_Group>; +def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group<g_Group>; +def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group<g_Group>; +def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>; +def gfull : Flag<["-"], "gfull">, Group<g_Group>; +def gused : Flag<["-"], "gused">, Group<g_Group>; +def gstabs : Joined<["-"], "gstabs">, Group<g_Group>, Flags<[Unsupported]>; +def gcoff : Joined<["-"], "gcoff">, Group<g_Group>, Flags<[Unsupported]>; +def gxcoff : Joined<["-"], "gxcoff">, Group<g_Group>, Flags<[Unsupported]>; +def gvms : Joined<["-"], "gvms">, Group<g_Group>, Flags<[Unsupported]>; +def gtoggle : Flag<["-"], "gtoggle">, Group<g_flags_Group>, Flags<[Unsupported]>; +def grecord_gcc_switches : Flag<["-"], "grecord-gcc-switches">, Group<g_flags_Group>; +def gno_record_gcc_switches : Flag<["-"], "gno-record-gcc-switches">, Group<g_flags_Group>; -def gstrict_dwarf : Flag<"-gstrict-dwarf">, Group<g_flags_Group>; -def gno_strict_dwarf : Flag<"-gno-strict-dwarf">, Group<g_flags_Group>; -def headerpad__max__install__names : Joined<"-headerpad_max_install_names">; -def help : Flag<"-help">, Flags<[CC1Option]>, +def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group<g_flags_Group>; +def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group<g_flags_Group>; +def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>; +def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">; +def help : Flag<["-", "--"], "help">, Flags<[CC1Option]>, HelpText<"Display available options">; -def index_header_map : Flag<"-index-header-map">, Flags<[CC1Option]>, +def index_header_map : Flag<["-"], "index-header-map">, Flags<[CC1Option]>, HelpText<"Make the next included directory (-I or -F) an indexer header map">; -def idirafter : JoinedOrSeparate<"-idirafter">, Group<clang_i_Group>, Flags<[CC1Option]>, +def idirafter : JoinedOrSeparate<["-"], "idirafter">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Add directory to AFTER include search path">; -def iframework : Joined<"-iframework">, Group<clang_i_Group>, Flags<[CC1Option]>, +def iframework : JoinedOrSeparate<["-"], "iframework">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Add directory to SYSTEM framework search path">; -def imacros : JoinedOrSeparate<"-imacros">, Group<clang_i_Group>, Flags<[CC1Option]>, +def imacros : JoinedOrSeparate<["-", "--"], "imacros">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Include macros from file before parsing">, MetaVarName<"<file>">; -def image__base : Separate<"-image_base">; -def include_ : JoinedOrSeparate<"-include">, Group<clang_i_Group>, EnumName<"include">, +def image__base : Separate<["-"], "image_base">; +def include_ : JoinedOrSeparate<["-", "--"], "include">, Group<clang_i_Group>, EnumName<"include">, MetaVarName<"<file>">, HelpText<"Include file before parsing">, Flags<[CC1Option]>; -def include_pch : Separate<"-include-pch">, Group<clang_i_Group>, Flags<[CC1Option]>, +def include_pch : Separate<["-"], "include-pch">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Include precompiled header file">, MetaVarName<"<file>">; -def init : Separate<"-init">; -def install__name : Separate<"-install_name">; -def integrated_as : Flag<"-integrated-as">, Flags<[DriverOption]>; -def iprefix : JoinedOrSeparate<"-iprefix">, Group<clang_i_Group>, Flags<[CC1Option]>, +def init : Separate<["-"], "init">; +def install__name : Separate<["-"], "install_name">; +def integrated_as : Flag<["-"], "integrated-as">, Flags<[DriverOption]>; +def iprefix : JoinedOrSeparate<["-"], "iprefix">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">, MetaVarName<"<dir>">; -def iquote : JoinedOrSeparate<"-iquote">, Group<clang_i_Group>, Flags<[CC1Option]>, +def iquote : JoinedOrSeparate<["-"], "iquote">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Add directory to QUOTE include search path">, MetaVarName<"<directory>">; -def isysroot : JoinedOrSeparate<"-isysroot">, Group<clang_i_Group>, Flags<[CC1Option]>, +def isysroot : JoinedOrSeparate<["-"], "isysroot">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Set the system root directory (usually /)">, MetaVarName<"<dir>">; -def isystem : JoinedOrSeparate<"-isystem">, Group<clang_i_Group>, Flags<[CC1Option]>, +def isystem : JoinedOrSeparate<["-"], "isystem">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Add directory to SYSTEM include search path">, MetaVarName<"<directory>">; -def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">, Group<clang_i_Group>, +def iwithprefixbefore : JoinedOrSeparate<["-"], "iwithprefixbefore">, Group<clang_i_Group>, HelpText<"Set directory to include search path with prefix">, MetaVarName<"<dir>">, Flags<[CC1Option]>; -def iwithprefix : JoinedOrSeparate<"-iwithprefix">, Group<clang_i_Group>, Flags<[CC1Option]>, +def iwithprefix : JoinedOrSeparate<["-"], "iwithprefix">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Set directory to SYSTEM include search path with prefix">, MetaVarName<"<dir>">; -def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">, Group<clang_i_Group>, +def iwithsysroot : JoinedOrSeparate<["-"], "iwithsysroot">, Group<clang_i_Group>, HelpText<"Add directory to SYSTEM include search path, " "absolute paths are relative to -isysroot">, MetaVarName<"<directory>">, Flags<[CC1Option]>; -def i : Joined<"-i">, Group<i_Group>; -def keep__private__externs : Flag<"-keep_private_externs">; -def l : JoinedOrSeparate<"-l">, Flags<[LinkerInput, RenderJoined]>; -def lazy__framework : Separate<"-lazy_framework">, Flags<[LinkerInput]>; -def lazy__library : Separate<"-lazy_library">, Flags<[LinkerInput]>; -def m32 : Flag<"-m32">, Group<m_Group>, Flags<[DriverOption]>; -def mqdsp6_compat : Flag<"-mqdsp6-compat">, Group<m_Group>, Flags<[DriverOption,CC1Option]>, +def i : Joined<["-"], "i">, Group<i_Group>; +def keep__private__externs : Flag<["-"], "keep_private_externs">; +def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>; +def lazy__framework : Separate<["-"], "lazy_framework">, Flags<[LinkerInput]>; +def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>; +def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[DriverOption]>; +def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>, Flags<[DriverOption,CC1Option]>, HelpText<"Enable hexagon-qdsp6 backward compatibility">; -def m3dnowa : Flag<"-m3dnowa">, Group<m_x86_Features_Group>; -def m3dnow : Flag<"-m3dnow">, Group<m_x86_Features_Group>; -def m64 : Flag<"-m64">, Group<m_Group>, Flags<[DriverOption]>; -def mabi_EQ : Joined<"-mabi=">, Group<m_Group>; -def march_EQ : Joined<"-march=">, Group<m_Group>; -def maltivec : Flag<"-maltivec">, Alias<faltivec>; -def mcmodel_EQ : Joined<"-mcmodel=">, Group<m_Group>; -def mconstant_cfstrings : Flag<"-mconstant-cfstrings">, Group<clang_ignored_m_Group>; -def mcpu_EQ : Joined<"-mcpu=">, Group<m_Group>; -def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>; -def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>; -def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>; -def mfpmath_EQ : Joined<"-mfpmath=">, 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>; -def mios_simulator_version_min_EQ : Joined<"-mios-simulator-version-min=">, Group<m_Group>; -def mkernel : Flag<"-mkernel">, Group<m_Group>; -def mlinker_version_EQ : Joined<"-mlinker-version=">, Flags<[NoForward]>; -def mllvm : Separate<"-mllvm">, Flags<[CC1Option]>, +def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>; +def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>; +def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption]>; +def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>; +def march_EQ : Joined<["-"], "march=">, Group<m_Group>; +def maltivec : Flag<["-"], "maltivec">, Alias<faltivec>; +def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>; +def mconstant_cfstrings : Flag<["-"], "mconstant-cfstrings">, Group<clang_ignored_m_Group>; +def mcpu_EQ : Joined<["-"], "mcpu=">, Group<m_Group>; +def mdynamic_no_pic : Joined<["-"], "mdynamic-no-pic">, Group<m_Group>; +def mfix_and_continue : Flag<["-"], "mfix-and-continue">, Group<clang_ignored_m_Group>; +def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>; +def mfpmath_EQ : Joined<["-"], "mfpmath=">, 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>; +def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">, Group<m_Group>; +def mkernel : Flag<["-"], "mkernel">, Group<m_Group>; +def mlinker_version_EQ : Joined<["-"], "mlinker-version=">, Flags<[NoForward]>; +def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option]>, HelpText<"Additional arguments to forward to LLVM's option processing">; -def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>; -def mms_bitfields : Flag<"-mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>, - HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard.">; -def mstackrealign : Flag<"-mstackrealign">, Group<m_Group>, Flags<[CC1Option]>, - HelpText<"Force realign the stack at entry to every function.">; -def mstack_alignment : Joined<"-mstack-alignment=">, Group<m_Group>, Flags<[CC1Option]>, +def mmacosx_version_min_EQ : Joined<["-"], "mmacosx-version-min=">, Group<m_Group>; +def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>, + HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">; +def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>, Flags<[CC1Option]>, + HelpText<"Force realign the stack at entry to every function">; +def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Set the stack alignment">; -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>, Flags<[CC1Option]>, +def mstrict_align : Flag<["-"], "mstrict-align">, Group<m_Group>, Flags<[CC1Option]>, + HelpText<"Force all memory accesses to be aligned (ARM only)">; +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>, Flags<[CC1Option]>, HelpText<"Disable merging of globals">; -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>; -def mno_relax_all : Flag<"-mno-relax-all">, Group<m_Group>; -def mno_rtd: Flag<"-mno-rtd">, Group<m_Group>; -def mno_soft_float : Flag<"-mno-soft-float">, Group<m_Group>; -def mno_stackrealign : Flag<"-mno-stackrealign">, Group<m_Group>; -def mno_sse2 : Flag<"-mno-sse2">, Group<m_x86_Features_Group>; -def mno_sse3 : Flag<"-mno-sse3">, Group<m_x86_Features_Group>; -def mno_sse4a : Flag<"-mno-sse4a">, Group<m_x86_Features_Group>; -def mno_sse4 : Flag<"-mno-sse4">, Group<m_x86_Features_Group>; -def mno_sse4_1 : Flag<"-mno-sse4.1">, Group<m_x86_Features_Group>; -def mno_sse4_2 : Flag<"-mno-sse4.2">, Group<m_x86_Features_Group>; -def mno_sse : Flag<"-mno-sse">, Group<m_x86_Features_Group>; -def mno_ssse3 : Flag<"-mno-ssse3">, Group<m_x86_Features_Group>; -def mno_aes : Flag<"-mno-aes">, Group<m_x86_Features_Group>; -def mno_avx : Flag<"-mno-avx">, Group<m_x86_Features_Group>; -def mno_avx2 : Flag<"-mno-avx2">, Group<m_x86_Features_Group>; -def mno_pclmul : Flag<"-mno-pclmul">, Group<m_x86_Features_Group>; -def mno_lzcnt : Flag<"-mno-lzcnt">, Group<m_x86_Features_Group>; -def mno_rdrnd : Flag<"-mno-rdrnd">, Group<m_x86_Features_Group>; -def mno_bmi : Flag<"-mno-bmi">, Group<m_x86_Features_Group>; -def mno_bmi2 : Flag<"-mno-bmi2">, Group<m_x86_Features_Group>; -def mno_popcnt : Flag<"-mno-popcnt">, Group<m_x86_Features_Group>; -def mno_fma4 : Flag<"-mno-fma4">, Group<m_x86_Features_Group>; -def mno_fma : Flag<"-mno-fma">, Group<m_x86_Features_Group>; -def mno_xop : Flag<"-mno-xop">, Group<m_x86_Features_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>; +def mno_relax_all : Flag<["-"], "mno-relax-all">, Group<m_Group>; +def mno_rtd: Flag<["-"], "mno-rtd">, Group<m_Group>; +def mno_soft_float : Flag<["-"], "mno-soft-float">, Group<m_Group>; +def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group<m_Group>; +def mno_sse2 : Flag<["-"], "mno-sse2">, Group<m_x86_Features_Group>; +def mno_sse3 : Flag<["-"], "mno-sse3">, Group<m_x86_Features_Group>; +def mno_sse4a : Flag<["-"], "mno-sse4a">, Group<m_x86_Features_Group>; +def mno_sse4 : Flag<["-"], "mno-sse4">, Group<m_x86_Features_Group>; +def mno_sse4_1 : Flag<["-"], "mno-sse4.1">, Group<m_x86_Features_Group>; +def mno_sse4_2 : Flag<["-"], "mno-sse4.2">, Group<m_x86_Features_Group>; +def mno_sse : Flag<["-"], "mno-sse">, Group<m_x86_Features_Group>; +def mno_ssse3 : Flag<["-"], "mno-ssse3">, Group<m_x86_Features_Group>; +def mno_aes : Flag<["-"], "mno-aes">, Group<m_x86_Features_Group>; +def mno_avx : Flag<["-"], "mno-avx">, Group<m_x86_Features_Group>; +def mno_avx2 : Flag<["-"], "mno-avx2">, Group<m_x86_Features_Group>; +def mno_pclmul : Flag<["-"], "mno-pclmul">, Group<m_x86_Features_Group>; +def mno_lzcnt : Flag<["-"], "mno-lzcnt">, Group<m_x86_Features_Group>; +def mno_rdrnd : Flag<["-"], "mno-rdrnd">, Group<m_x86_Features_Group>; +def mno_bmi : Flag<["-"], "mno-bmi">, Group<m_x86_Features_Group>; +def mno_bmi2 : Flag<["-"], "mno-bmi2">, Group<m_x86_Features_Group>; +def mno_popcnt : Flag<["-"], "mno-popcnt">, Group<m_x86_Features_Group>; +def mno_fma4 : Flag<["-"], "mno-fma4">, Group<m_x86_Features_Group>; +def mno_fma : Flag<["-"], "mno-fma">, Group<m_x86_Features_Group>; +def mno_xop : Flag<["-"], "mno-xop">, Group<m_x86_Features_Group>; +def mno_f16c : Flag<["-"], "mno-f16c">, Group<m_x86_Features_Group>; +def mno_rtm : Flag<["-"], "mno-rtm">, Group<m_x86_Features_Group>; -def mno_thumb : Flag<"-mno-thumb">, Group<m_Group>; -def marm : Flag<"-marm">, Alias<mno_thumb>; +def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_Group>; +def marm : Flag<["-"], "marm">, Alias<mno_thumb>; -def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Group<m_Group>; -def mno_omit_leaf_frame_pointer : Flag<"-mno-omit-leaf-frame-pointer">, Group<f_Group>; -def momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">, Group<f_Group>, - HelpText<"Omit frame pointer setup for leaf functions.">, Flags<[CC1Option]>; -def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>; -def mred_zone : Flag<"-mred-zone">, Group<m_Group>; -def mregparm_EQ : Joined<"-mregparm=">, Group<m_Group>; -def mrelax_all : Flag<"-mrelax-all">, Group<m_Group>, Flags<[CC1Option]>, +def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings">, Group<m_Group>; +def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>; +def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>, + HelpText<"Omit frame pointer setup for leaf functions">, Flags<[CC1Option]>; +def mpascal_strings : Flag<["-"], "mpascal-strings">, Group<m_Group>; +def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>; +def mregparm_EQ : Joined<["-"], "mregparm=">, Group<m_Group>; +def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"(integrated-as) Relax all machine instructions">; -def mrtd : Flag<"-mrtd">, Group<m_Group>, Flags<[CC1Option]>, +def mrtd : Flag<["-"], "mrtd">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Make StdCall calling convention the default">; -def msmall_data_threshold_EQ : Joined <"-msmall-data-threshold=">, Group<m_Group>; -def msoft_float : Flag<"-msoft-float">, Group<m_Group>, Flags<[CC1Option]>, +def msmall_data_threshold_EQ : Joined <["-"], "msmall-data-threshold=">, Group<m_Group>; +def msoft_float : Flag<["-"], "msoft-float">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Use software floating point">; -def mno_implicit_float : Flag<"-mno-implicit-float">, Group<m_Group>, +def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>, HelpText<"Don't generate implicit floating point instructions">; -def msse2 : Flag<"-msse2">, Group<m_x86_Features_Group>; -def msse3 : Flag<"-msse3">, Group<m_x86_Features_Group>; -def msse4a : Flag<"-msse4a">, Group<m_x86_Features_Group>; -def msse4 : Flag<"-msse4">, Group<m_x86_Features_Group>; -def msse4_1 : Flag<"-msse4.1">, Group<m_x86_Features_Group>; -def msse4_2 : Flag<"-msse4.2">, Group<m_x86_Features_Group>; -def msse : Flag<"-msse">, Group<m_x86_Features_Group>; -def mssse3 : Flag<"-mssse3">, Group<m_x86_Features_Group>; -def maes : Flag<"-maes">, Group<m_x86_Features_Group>; -def mavx : Flag<"-mavx">, Group<m_x86_Features_Group>; -def mavx2 : Flag<"-mavx2">, Group<m_x86_Features_Group>; -def mpclmul : Flag<"-mpclmul">, Group<m_x86_Features_Group>; -def mlzcnt : Flag<"-mlzcnt">, Group<m_x86_Features_Group>; -def mrdrnd : Flag<"-mrdrnd">, Group<m_x86_Features_Group>; -def mbmi : Flag<"-mbmi">, Group<m_x86_Features_Group>; -def mbmi2 : Flag<"-mbmi2">, Group<m_x86_Features_Group>; -def mpopcnt : Flag<"-mpopcnt">, Group<m_x86_Features_Group>; -def mfma4 : Flag<"-mfma4">, Group<m_x86_Features_Group>; -def mfma : Flag<"-mfma">, Group<m_x86_Features_Group>; -def mxop : Flag<"-mxop">, Group<m_x86_Features_Group>; -def mips16 : Flag<"-mips16">, Group<m_Group>; -def mno_mips16 : Flag<"-mno-mips16">, Group<m_Group>; -def mdsp : Flag<"-mdsp">, Group<m_Group>; -def mno_dsp : Flag<"-mno-dsp">, Group<m_Group>; -def mdspr2 : Flag<"-mdspr2">, Group<m_Group>; -def mno_dspr2 : Flag<"-mno-dspr2">, Group<m_Group>; -def mthumb : Flag<"-mthumb">, Group<m_Group>; -def mtune_EQ : Joined<"-mtune=">, Group<m_Group>; -def multi__module : Flag<"-multi_module">; -def multiply__defined__unused : Separate<"-multiply_defined_unused">; -def multiply__defined : Separate<"-multiply_defined">; -def mwarn_nonportable_cfstrings : Flag<"-mwarn-nonportable-cfstrings">, Group<m_Group>; -def m_Separate : Separate<"-m">, Group<m_Group>; -def m_Joined : Joined<"-m">, Group<m_Group>; -def no_canonical_prefixes : Flag<"-no-canonical-prefixes">, Flags<[HelpHidden]>, +def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>; +def msse3 : Flag<["-"], "msse3">, Group<m_x86_Features_Group>; +def msse4a : Flag<["-"], "msse4a">, Group<m_x86_Features_Group>; +def msse4 : Flag<["-"], "msse4">, Group<m_x86_Features_Group>; +def msse4_1 : Flag<["-"], "msse4.1">, Group<m_x86_Features_Group>; +def msse4_2 : Flag<["-"], "msse4.2">, Group<m_x86_Features_Group>; +def msse : Flag<["-"], "msse">, Group<m_x86_Features_Group>; +def mssse3 : Flag<["-"], "mssse3">, Group<m_x86_Features_Group>; +def maes : Flag<["-"], "maes">, Group<m_x86_Features_Group>; +def mavx : Flag<["-"], "mavx">, Group<m_x86_Features_Group>; +def mavx2 : Flag<["-"], "mavx2">, Group<m_x86_Features_Group>; +def mpclmul : Flag<["-"], "mpclmul">, Group<m_x86_Features_Group>; +def mlzcnt : Flag<["-"], "mlzcnt">, Group<m_x86_Features_Group>; +def mrdrnd : Flag<["-"], "mrdrnd">, Group<m_x86_Features_Group>; +def mbmi : Flag<["-"], "mbmi">, Group<m_x86_Features_Group>; +def mbmi2 : Flag<["-"], "mbmi2">, Group<m_x86_Features_Group>; +def mpopcnt : Flag<["-"], "mpopcnt">, Group<m_x86_Features_Group>; +def mfma4 : Flag<["-"], "mfma4">, Group<m_x86_Features_Group>; +def mfma : Flag<["-"], "mfma">, Group<m_x86_Features_Group>; +def mxop : Flag<["-"], "mxop">, Group<m_x86_Features_Group>; +def mf16c : Flag<["-"], "mf16c">, Group<m_x86_Features_Group>; +def mrtm : Flag<["-"], "mrtm">, Group<m_x86_Features_Group>; +def mips16 : Flag<["-"], "mips16">, Group<m_Group>; +def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>; +def mdsp : Flag<["-"], "mdsp">, Group<m_Group>; +def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_Group>; +def mdspr2 : Flag<["-"], "mdspr2">, Group<m_Group>; +def mno_dspr2 : Flag<["-"], "mno-dspr2">, Group<m_Group>; +def mips32 : Flag<["-"], "mips32">, Group<mips_CPUs_Group>, + HelpText<"Equivalent to -march=mips32">, Flags<[HelpHidden]>; +def mips32r2 : Flag<["-"], "mips32r2">, Group<mips_CPUs_Group>, + HelpText<"Equivalent to -march=mips32r2">, Flags<[HelpHidden]>; +def mips64 : Flag<["-"], "mips64">, Group<mips_CPUs_Group>, + HelpText<"Equivalent to -march=mips64">, Flags<[HelpHidden]>; +def mips64r2 : Flag<["-"], "mips64r2">, Group<mips_CPUs_Group>, + HelpText<"Equivalent to -march=mips64r2">, Flags<[HelpHidden]>; +def mthumb : Flag<["-"], "mthumb">, Group<m_Group>; +def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>; +def multi__module : Flag<["-"], "multi_module">; +def multiply__defined__unused : Separate<["-"], "multiply_defined_unused">; +def multiply__defined : Separate<["-"], "multiply_defined">; +def mwarn_nonportable_cfstrings : Flag<["-"], "mwarn-nonportable-cfstrings">, Group<m_Group>; +def m_Separate : Separate<["-"], "m">, Group<m_Group>; +def m_Joined : Joined<["-"], "m">, Group<m_Group>; +def no_canonical_prefixes : Flag<["-"], "no-canonical-prefixes">, Flags<[HelpHidden]>, HelpText<"Use relative instead of canonical paths">; -def no_cpp_precomp : Flag<"-no-cpp-precomp">, Group<clang_ignored_f_Group>; -def no_integrated_as : Flag<"-no-integrated-as">, Flags<[DriverOption]>; -def no_integrated_cpp : Flag<"-no-integrated-cpp">, Flags<[DriverOption]>; -def no_pedantic : Flag<"-no-pedantic">, Group<pedantic_Group>; -def no__dead__strip__inits__and__terms : Flag<"-no_dead_strip_inits_and_terms">; -def nobuiltininc : Flag<"-nobuiltininc">, Flags<[CC1Option]>, +def no_cpp_precomp : Flag<["-"], "no-cpp-precomp">, Group<clang_ignored_f_Group>; +def no_integrated_as : Flag<["-"], "no-integrated-as">, Flags<[DriverOption]>; +def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">, Flags<[DriverOption]>; +def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>; +def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">; +def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option]>, HelpText<"Disable builtin #include directories">; -def nodefaultlibs : Flag<"-nodefaultlibs">; -def nofixprebinding : Flag<"-nofixprebinding">; -def nolibc : Flag<"-nolibc">; -def nomultidefs : Flag<"-nomultidefs">; -def noprebind : Flag<"-noprebind">; -def noseglinkedit : Flag<"-noseglinkedit">; -def nostartfiles : Flag<"-nostartfiles">; -def nostdinc : Flag<"-nostdinc">; -def nostdlibinc : Flag<"-nostdlibinc">; -def nostdincxx : Flag<"-nostdinc++">, Flags<[CC1Option]>, +def nodefaultlibs : Flag<["-"], "nodefaultlibs">; +def nofixprebinding : Flag<["-"], "nofixprebinding">; +def nolibc : Flag<["-"], "nolibc">; +def nomultidefs : Flag<["-"], "nomultidefs">; +def noprebind : Flag<["-"], "noprebind">; +def noseglinkedit : Flag<["-"], "noseglinkedit">; +def nostartfiles : Flag<["-"], "nostartfiles">; +def nostdinc : Flag<["-"], "nostdinc">; +def nostdlibinc : Flag<["-"], "nostdlibinc">; +def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>, HelpText<"Disable standard #include directories for the C++ standard library">; -def nostdlib : Flag<"-nostdlib">; -def object : Flag<"-object">; -def o : JoinedOrSeparate<"-o">, Flags<[DriverOption, RenderAsInput, CC1Option]>, +def nostdlib : Flag<["-"], "nostdlib">; +def object : Flag<["-"], "object">; +def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option]>, HelpText<"Write output to <file>">, MetaVarName<"<file>">; -def pagezero__size : JoinedOrSeparate<"-pagezero_size">; -def pass_exit_codes : Flag<"-pass-exit-codes">, Flags<[Unsupported]>; -def pedantic_errors : Flag<"-pedantic-errors">, Group<pedantic_Group>, Flags<[CC1Option]>; -def pedantic : Flag<"-pedantic">, Group<pedantic_Group>, Flags<[CC1Option]>; -def pg : Flag<"-pg">, HelpText<"Enable mcount instrumentation">, Flags<[CC1Option]>; -def pipe : Flag<"-pipe">, +def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">; +def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>; +def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group<pedantic_Group>, Flags<[CC1Option]>; +def pedantic : Flag<["-", "--"], "pedantic">, Group<pedantic_Group>, Flags<[CC1Option]>; +def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">, Flags<[CC1Option]>; +def pipe : Flag<["-", "--"], "pipe">, HelpText<"Use pipes between commands, when possible">; -def prebind__all__twolevel__modules : Flag<"-prebind_all_twolevel_modules">; -def prebind : Flag<"-prebind">; -def preload : Flag<"-preload">; -def print_file_name_EQ : Joined<"-print-file-name=">, +def prebind__all__twolevel__modules : Flag<["-"], "prebind_all_twolevel_modules">; +def prebind : Flag<["-"], "prebind">; +def preload : Flag<["-"], "preload">; +def print_file_name_EQ : Joined<["-", "--"], "print-file-name=">, HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">; -def print_ivar_layout : Flag<"-print-ivar-layout">, Flags<[CC1Option]>, +def print_ivar_layout : Flag<["-"], "print-ivar-layout">, Flags<[CC1Option]>, HelpText<"Enable Objective-C Ivar layout bitmap print trace">; -def print_libgcc_file_name : Flag<"-print-libgcc-file-name">, +def print_libgcc_file_name : Flag<["-", "--"], "print-libgcc-file-name">, HelpText<"Print the library path for \"libgcc.a\"">; -def print_multi_directory : Flag<"-print-multi-directory">; -def print_multi_lib : Flag<"-print-multi-lib">; -def print_multi_os_directory : Flag<"-print-multi-os-directory">; -def print_prog_name_EQ : Joined<"-print-prog-name=">, +def print_multi_directory : Flag<["-", "--"], "print-multi-directory">; +def print_multi_lib : Flag<["-", "--"], "print-multi-lib">; +def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">; +def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">, HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">; -def print_search_dirs : Flag<"-print-search-dirs">, +def print_search_dirs : Flag<["-", "--"], "print-search-dirs">, HelpText<"Print the paths used for finding libraries and programs">; -def private__bundle : Flag<"-private_bundle">; -def pthreads : Flag<"-pthreads">; -def pthread : Flag<"-pthread">, Flags<[CC1Option]>, +def private__bundle : Flag<["-"], "private_bundle">; +def pthreads : Flag<["-"], "pthreads">; +def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>, HelpText<"Support POSIX threads in generated code">; -def p : Flag<"-p">; -def pie : Flag<"-pie">; -def read__only__relocs : Separate<"-read_only_relocs">; -def remap : Flag<"-remap">; -def rewrite_objc : Flag<"-rewrite-objc">, Flags<[DriverOption,CC1Option]>, +def p : Flag<["-"], "p">; +def pie : Flag<["-"], "pie">; +def read__only__relocs : Separate<["-"], "read_only_relocs">; +def remap : Flag<["-"], "remap">; +def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>, HelpText<"Rewrite Objective-C source to C++">, Group<Action_Group>; -def rewrite_legacy_objc : Flag<"-rewrite-legacy-objc">, Flags<[DriverOption]>, +def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">, Flags<[DriverOption]>, HelpText<"Rewrite Legacy Objective-C source to C++">; -def rdynamic : Flag<"-rdynamic">; -def rpath : Separate<"-rpath">, Flags<[LinkerInput]>; -def rtlib_EQ : Joined<"-rtlib=">; -def r : Flag<"-r">; -def save_temps : Flag<"-save-temps">, Flags<[DriverOption]>, +def rdynamic : Flag<["-"], "rdynamic">; +def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>; +def rtlib_EQ : Joined<["-", "--"], "rtlib=">; +def r : Flag<["-"], "r">; +def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>, HelpText<"Save intermediate compilation results">; -def sectalign : MultiArg<"-sectalign", 3>; -def sectcreate : MultiArg<"-sectcreate", 3>; -def sectobjectsymbols : MultiArg<"-sectobjectsymbols", 2>; -def sectorder : MultiArg<"-sectorder", 3>; -def seg1addr : JoinedOrSeparate<"-seg1addr">; -def seg__addr__table__filename : Separate<"-seg_addr_table_filename">; -def seg__addr__table : Separate<"-seg_addr_table">; -def segaddr : MultiArg<"-segaddr", 2>; -def segcreate : MultiArg<"-segcreate", 3>; -def seglinkedit : Flag<"-seglinkedit">; -def segprot : MultiArg<"-segprot", 3>; -def segs__read__only__addr : Separate<"-segs_read_only_addr">; -def segs__read__write__addr : Separate<"-segs_read_write_addr">; -def segs__read__ : Joined<"-segs_read_">; -def shared_libgcc : Flag<"-shared-libgcc">; -def shared : Flag<"-shared">; -def single__module : Flag<"-single_module">; -def specs_EQ : Joined<"-specs=">; -def specs : Separate<"-specs">, Flags<[Unsupported]>; -def static_libgcc : Flag<"-static-libgcc">; -def static_libstdcxx : Flag<"-static-libstdc++">; -def static : Flag<"-static">, Flags<[NoArgumentUnused]>; -def std_default_EQ : Joined<"-std-default=">; -def std_EQ : Joined<"-std=">, Flags<[CC1Option]>, Group<L_Group>, +def sectalign : MultiArg<["-"], "sectalign", 3>; +def sectcreate : MultiArg<["-"], "sectcreate", 3>; +def sectobjectsymbols : MultiArg<["-"], "sectobjectsymbols", 2>; +def sectorder : MultiArg<["-"], "sectorder", 3>; +def seg1addr : JoinedOrSeparate<["-"], "seg1addr">; +def seg__addr__table__filename : Separate<["-"], "seg_addr_table_filename">; +def seg__addr__table : Separate<["-"], "seg_addr_table">; +def segaddr : MultiArg<["-"], "segaddr", 2>; +def segcreate : MultiArg<["-"], "segcreate", 3>; +def seglinkedit : Flag<["-"], "seglinkedit">; +def segprot : MultiArg<["-"], "segprot", 3>; +def segs__read__only__addr : Separate<["-"], "segs_read_only_addr">; +def segs__read__write__addr : Separate<["-"], "segs_read_write_addr">; +def segs__read__ : Joined<["-"], "segs_read_">; +def shared_libgcc : Flag<["-"], "shared-libgcc">; +def shared : Flag<["-", "--"], "shared">; +def single__module : Flag<["-"], "single_module">; +def specs_EQ : Joined<["-", "--"], "specs=">; +def specs : Separate<["-", "--"], "specs">, Flags<[Unsupported]>; +def static_libgcc : Flag<["-"], "static-libgcc">; +def static_libstdcxx : Flag<["-"], "static-libstdc++">; +def static : Flag<["-", "--"], "static">, Flags<[NoArgumentUnused]>; +def std_default_EQ : Joined<["-"], "std-default=">; +def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>, Group<L_Group>, HelpText<"Language standard to compile for">; -def stdlib_EQ : Joined<"-stdlib=">, Flags<[CC1Option]>, +def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>, HelpText<"C++ standard library to use">; -def sub__library : JoinedOrSeparate<"-sub_library">; -def sub__umbrella : JoinedOrSeparate<"-sub_umbrella">; -def s : Flag<"-s">; -def target : Separate<"-target">, Flags<[DriverOption]>, +def sub__library : JoinedOrSeparate<["-"], "sub_library">; +def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">; +def s : Flag<["-"], "s">; +def target : Separate<["-"], "target">, Flags<[DriverOption]>, HelpText<"Generate code for the given target">; -def gcc_toolchain : Separate<"-gcc-toolchain">, Flags<[DriverOption]>, +def gcc_toolchain : Separate<["-"], "gcc-toolchain">, Flags<[DriverOption]>, HelpText<"Use the gcc toolchain at the given directory">; -// We should deprecate the use of -ccc-host-triple, and then remove. -def ccc_host_triple : Separate<"-ccc-host-triple">, Alias<target>; -def time : Flag<"-time">, +def time : Flag<["-"], "time">, HelpText<"Time individual commands">; -def traditional_cpp : Flag<"-traditional-cpp">, Flags<[CC1Option]>, +def traditional_cpp : Flag<["-", "--"], "traditional-cpp">, Flags<[CC1Option]>, HelpText<"Enable some traditional CPP emulation">; -def traditional : Flag<"-traditional">; -def trigraphs : Flag<"-trigraphs">, Flags<[CC1Option]>, +def traditional : Flag<["-", "--"], "traditional">; +def trigraphs : Flag<["-", "--"], "trigraphs">, Flags<[CC1Option]>, HelpText<"Process trigraph sequences">; -def twolevel__namespace__hints : Flag<"-twolevel_namespace_hints">; -def twolevel__namespace : Flag<"-twolevel_namespace">; -def t : Flag<"-t">; -def umbrella : Separate<"-umbrella">; -def undefined : JoinedOrSeparate<"-undefined">, Group<u_Group>; -def undef : Flag<"-undef">, Group<u_Group>, Flags<[CC1Option]>, +def twolevel__namespace__hints : Flag<["-"], "twolevel_namespace_hints">; +def twolevel__namespace : Flag<["-"], "twolevel_namespace">; +def t : Flag<["-"], "t">; +def umbrella : Separate<["-"], "umbrella">; +def undefined : JoinedOrSeparate<["-"], "undefined">, Group<u_Group>; +def undef : Flag<["-"], "undef">, Group<u_Group>, Flags<[CC1Option]>, HelpText<"undef all system defines">; -def unexported__symbols__list : Separate<"-unexported_symbols_list">; -def u : JoinedOrSeparate<"-u">, Group<u_Group>; -def use_gold_plugin : Flag<"-use-gold-plugin">; -def v : Flag<"-v">, Flags<[CC1Option]>, +def unexported__symbols__list : Separate<["-"], "unexported_symbols_list">; +def u : JoinedOrSeparate<["-"], "u">, Group<u_Group>; +def use_gold_plugin : Flag<["-"], "use-gold-plugin">; +def v : Flag<["-"], "v">, Flags<[CC1Option]>, HelpText<"Show commands to run and use verbose output">; -def verify : Flag<"-verify">, Flags<[DriverOption,CC1Option]>, - 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]>; -def weak__reference__mismatches : Separate<"-weak_reference_mismatches">; -def whatsloaded : Flag<"-whatsloaded">; -def whyload : Flag<"-whyload">; -def w : Flag<"-w">, HelpText<"Suppress all warnings.">, Flags<[CC1Option]>; -def x : JoinedOrSeparate<"-x">, Flags<[DriverOption,CC1Option]>, +def verify : Flag<["-"], "verify">, Flags<[DriverOption,CC1Option]>, + 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]>; +def weak__reference__mismatches : Separate<["-"], "weak_reference_mismatches">; +def whatsloaded : Flag<["-"], "whatsloaded">; +def whyload : Flag<["-"], "whyload">; +def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option]>; +def x : JoinedOrSeparate<["-"], "x">, Flags<[DriverOption,CC1Option]>, HelpText<"Treat subsequent input files as having type <language>">, MetaVarName<"<language>">; -def y : Joined<"-y">; +def y : Joined<["-"], "y">; -def working_directory : JoinedOrSeparate<"-working-directory">, Flags<[CC1Option]>, +def working_directory : JoinedOrSeparate<["-"], "working-directory">, Flags<[CC1Option]>, HelpText<"Resolve file paths relative to the specified directory">; -def working_directory_EQ : Joined<"-working-directory=">, Flags<[CC1Option]>, +def working_directory_EQ : Joined<["-"], "working-directory=">, Flags<[CC1Option]>, Alias<working_directory>; // Double dash options, which are usually an alias for one of the previous // options. -def _CLASSPATH_EQ : Joined<"--CLASSPATH=">, Alias<fclasspath_EQ>; -def _CLASSPATH : Separate<"--CLASSPATH">, Alias<fclasspath_EQ>; -def _all_warnings : Flag<"--all-warnings">, Alias<Wall>; -def _analyze_auto : Flag<"--analyze-auto">, Flags<[DriverOption]>; -def _analyzer_no_default_checks : Flag<"--analyzer-no-default-checks">, Flags<[DriverOption]>; -def _analyzer_output : JoinedOrSeparate<"--analyzer-output">, Flags<[DriverOption]>; -def _analyze : Flag<"--analyze">, Flags<[DriverOption]>, +def _CLASSPATH_EQ : Joined<["--"], "CLASSPATH=">, Alias<fclasspath_EQ>; +def _CLASSPATH : Separate<["--"], "CLASSPATH">, Alias<fclasspath_EQ>; +def _all_warnings : Flag<["--"], "all-warnings">, Alias<Wall>; +def _analyze_auto : Flag<["--"], "analyze-auto">, Flags<[DriverOption]>; +def _analyzer_no_default_checks : Flag<["--"], "analyzer-no-default-checks">, Flags<[DriverOption]>; +def _analyzer_output : JoinedOrSeparate<["--"], "analyzer-output">, Flags<[DriverOption]>; +def _analyze : Flag<["--"], "analyze">, Flags<[DriverOption]>, HelpText<"Run the static analyzer">; -def _ansi : Flag<"--ansi">, Alias<ansi>; -def _assemble : Flag<"--assemble">, Alias<S>; -def _assert_EQ : Joined<"--assert=">, Alias<A>; -def _assert : Separate<"--assert">, Alias<A>; -def _bootclasspath_EQ : Joined<"--bootclasspath=">, Alias<fbootclasspath_EQ>; -def _bootclasspath : Separate<"--bootclasspath">, Alias<fbootclasspath_EQ>; -def _classpath_EQ : Joined<"--classpath=">, Alias<fclasspath_EQ>; -def _classpath : Separate<"--classpath">, Alias<fclasspath_EQ>; -def _combine : Flag<"--combine">, Alias<combine>; -def _comments_in_macros : Flag<"--comments-in-macros">, Alias<CC>; -def _comments : Flag<"--comments">, Alias<C>; -def _compile : Flag<"--compile">, Alias<c>; -def _constant_cfstrings : Flag<"--constant-cfstrings">; -def _coverage : Flag<"--coverage">, Alias<coverage>; -def _debug_EQ : Joined<"--debug=">, Alias<g_Flag>; -def _debug : Flag<"--debug">, Alias<g_Flag>; -def _define_macro_EQ : Joined<"--define-macro=">, Alias<D>; -def _define_macro : Separate<"--define-macro">, Alias<D>; -def _dependencies : Flag<"--dependencies">, Alias<M>; -def _encoding_EQ : Joined<"--encoding=">, Alias<fencoding_EQ>; -def _encoding : Separate<"--encoding">, Alias<fencoding_EQ>; -def _entry : Flag<"--entry">, Alias<e>; -def _extdirs_EQ : Joined<"--extdirs=">, Alias<fextdirs_EQ>; -def _extdirs : Separate<"--extdirs">, Alias<fextdirs_EQ>; -def _extra_warnings : Flag<"--extra-warnings">, Alias<W_Joined>; -def _for_linker_EQ : Joined<"--for-linker=">, Alias<Xlinker>; -def _for_linker : Separate<"--for-linker">, Alias<Xlinker>; -def _force_link_EQ : Joined<"--force-link=">, Alias<u>; -def _force_link : Separate<"--force-link">, Alias<u>; -def _help_hidden : Flag<"--help-hidden">; -def _help : Flag<"--help">, Alias<help>; -def _imacros_EQ : Joined<"--imacros=">, Alias<imacros>; -def _imacros : Separate<"--imacros">, Alias<imacros>; -def _include_barrier : Flag<"--include-barrier">, Alias<I_>; -def _include_directory_after_EQ : Joined<"--include-directory-after=">, Alias<idirafter>; -def _include_directory_after : Separate<"--include-directory-after">, Alias<idirafter>; -def _include_directory_EQ : Joined<"--include-directory=">, Alias<I>; -def _include_directory : Separate<"--include-directory">, Alias<I>; -def _include_prefix_EQ : Joined<"--include-prefix=">, Alias<iprefix>; -def _include_prefix : Separate<"--include-prefix">, Alias<iprefix>; -def _include_with_prefix_after_EQ : Joined<"--include-with-prefix-after=">, Alias<iwithprefix>; -def _include_with_prefix_after : Separate<"--include-with-prefix-after">, Alias<iwithprefix>; -def _include_with_prefix_before_EQ : Joined<"--include-with-prefix-before=">, Alias<iwithprefixbefore>; -def _include_with_prefix_before : Separate<"--include-with-prefix-before">, Alias<iwithprefixbefore>; -def _include_with_prefix_EQ : Joined<"--include-with-prefix=">, Alias<iwithprefix>; -def _include_with_prefix : Separate<"--include-with-prefix">, Alias<iwithprefix>; -def _include_EQ : Joined<"--include=">, Alias<include_>; -def _include : Separate<"--include">, Alias<include_>; -def _language_EQ : Joined<"--language=">, Alias<x>; -def _language : Separate<"--language">, Alias<x>; -def _library_directory_EQ : Joined<"--library-directory=">, Alias<L>; -def _library_directory : Separate<"--library-directory">, Alias<L>; -def _machine__EQ : Joined<"--machine-=">, Alias<m_Joined>; -def _machine_ : Joined<"--machine-">, Alias<m_Joined>; -def _machine_EQ : Joined<"--machine=">, Alias<m_Joined>; -def _machine : Separate<"--machine">, Alias<m_Joined>; -def _no_integrated_cpp : Flag<"--no-integrated-cpp">, Alias<no_integrated_cpp>; -def _no_line_commands : Flag<"--no-line-commands">, Alias<P>; -def _no_pedantic : Flag<"--no-pedantic">, Alias<no_pedantic>; -def _no_standard_includes : Flag<"--no-standard-includes">, Alias<nostdinc>; -def _no_standard_libraries : Flag<"--no-standard-libraries">, Alias<nostdlib>; -def _no_undefined : Flag<"--no-undefined">, Flags<[LinkerInput]>; -def _no_warnings : Flag<"--no-warnings">, Alias<w>; -def _optimize_EQ : Joined<"--optimize=">, Alias<O>; -def _optimize : Flag<"--optimize">, Alias<O>; -def _output_class_directory_EQ : Joined<"--output-class-directory=">, Alias<foutput_class_dir_EQ>; -def _output_class_directory : Separate<"--output-class-directory">, Alias<foutput_class_dir_EQ>; -def _output_EQ : Joined<"--output=">, Alias<o>; -def _output : Separate<"--output">, Alias<o>; -def _param : Separate<"--param">; -def _param_EQ : Joined<"--param=">, Alias<_param>; -def _pass_exit_codes : Flag<"--pass-exit-codes">, Alias<pass_exit_codes>; -def _pedantic_errors : Flag<"--pedantic-errors">, Alias<pedantic_errors>; -def _pedantic : Flag<"--pedantic">, Alias<pedantic>; -def _pipe : Flag<"--pipe">, Alias<pipe>; -def _prefix_EQ : Joined<"--prefix=">, Alias<B>; -def _prefix : Separate<"--prefix">, Alias<B>; -def _preprocess : Flag<"--preprocess">, Alias<E>; -def _print_diagnostic_categories : Flag<"--print-diagnostic-categories">; -def _print_file_name_EQ : Joined<"--print-file-name=">, Alias<print_file_name_EQ>; -def _print_file_name : Separate<"--print-file-name">, Alias<print_file_name_EQ>; -def _print_libgcc_file_name : Flag<"--print-libgcc-file-name">, Alias<print_libgcc_file_name>; -def _print_missing_file_dependencies : Flag<"--print-missing-file-dependencies">, Alias<MG>; -def _print_multi_directory : Flag<"--print-multi-directory">, Alias<print_multi_directory>; -def _print_multi_lib : Flag<"--print-multi-lib">, Alias<print_multi_lib>; -def _print_multi_os_directory : Flag<"--print-multi-os-directory">, Alias<print_multi_os_directory>; -def _print_prog_name_EQ : Joined<"--print-prog-name=">, Alias<print_prog_name_EQ>; -def _print_prog_name : Separate<"--print-prog-name">, Alias<print_prog_name_EQ>; -def _print_search_dirs : Flag<"--print-search-dirs">, Alias<print_search_dirs>; -def _profile_blocks : Flag<"--profile-blocks">, Alias<a>; -def _profile : Flag<"--profile">, Alias<p>; -def _relocatable_pch : Flag<"--relocatable-pch">, - HelpText<"Build a relocatable precompiled header">; -def _resource_EQ : Joined<"--resource=">, Alias<fcompile_resource_EQ>; -def _resource : Separate<"--resource">, Alias<fcompile_resource_EQ>; -def _rtlib_EQ : Joined<"--rtlib=">, Alias<rtlib_EQ>; -def _rtlib : Separate<"--rtlib">, Alias<rtlib_EQ>; -def _save_temps : Flag<"--save-temps">, Alias<save_temps>; -def _serialize_diags : Separate<"--serialize-diagnostics">, Flags<[DriverOption]>, +def _assemble : Flag<["--"], "assemble">, Alias<S>; +def _assert_EQ : Joined<["--"], "assert=">, Alias<A>; +def _assert : Separate<["--"], "assert">, Alias<A>; +def _bootclasspath_EQ : Joined<["--"], "bootclasspath=">, Alias<fbootclasspath_EQ>; +def _bootclasspath : Separate<["--"], "bootclasspath">, Alias<fbootclasspath_EQ>; +def _classpath_EQ : Joined<["--"], "classpath=">, Alias<fclasspath_EQ>; +def _classpath : Separate<["--"], "classpath">, Alias<fclasspath_EQ>; +def _comments_in_macros : Flag<["--"], "comments-in-macros">, Alias<CC>; +def _comments : Flag<["--"], "comments">, Alias<C>; +def _compile : Flag<["--"], "compile">, Alias<c>; +def _constant_cfstrings : Flag<["--"], "constant-cfstrings">; +def _debug_EQ : Joined<["--"], "debug=">, Alias<g_Flag>; +def _debug : Flag<["--"], "debug">, Alias<g_Flag>; +def _define_macro_EQ : Joined<["--"], "define-macro=">, Alias<D>; +def _define_macro : Separate<["--"], "define-macro">, Alias<D>; +def _dependencies : Flag<["--"], "dependencies">, Alias<M>; +def _encoding_EQ : Joined<["--"], "encoding=">, Alias<fencoding_EQ>; +def _encoding : Separate<["--"], "encoding">, Alias<fencoding_EQ>; +def _entry : Flag<["--"], "entry">, Alias<e>; +def _extdirs_EQ : Joined<["--"], "extdirs=">, Alias<fextdirs_EQ>; +def _extdirs : Separate<["--"], "extdirs">, Alias<fextdirs_EQ>; +def _extra_warnings : Flag<["--"], "extra-warnings">, Alias<W_Joined>; +def _for_linker_EQ : Joined<["--"], "for-linker=">, Alias<Xlinker>; +def _for_linker : Separate<["--"], "for-linker">, Alias<Xlinker>; +def _force_link_EQ : Joined<["--"], "force-link=">, Alias<u>; +def _force_link : Separate<["--"], "force-link">, Alias<u>; +def _help_hidden : Flag<["--"], "help-hidden">; +def _imacros_EQ : Joined<["--"], "imacros=">, Alias<imacros>; +def _include_barrier : Flag<["--"], "include-barrier">, Alias<I_>; +def _include_directory_after_EQ : Joined<["--"], "include-directory-after=">, Alias<idirafter>; +def _include_directory_after : Separate<["--"], "include-directory-after">, Alias<idirafter>; +def _include_directory_EQ : Joined<["--"], "include-directory=">, Alias<I>; +def _include_directory : Separate<["--"], "include-directory">, Alias<I>; +def _include_prefix_EQ : Joined<["--"], "include-prefix=">, Alias<iprefix>; +def _include_prefix : Separate<["--"], "include-prefix">, Alias<iprefix>; +def _include_with_prefix_after_EQ : Joined<["--"], "include-with-prefix-after=">, Alias<iwithprefix>; +def _include_with_prefix_after : Separate<["--"], "include-with-prefix-after">, Alias<iwithprefix>; +def _include_with_prefix_before_EQ : Joined<["--"], "include-with-prefix-before=">, Alias<iwithprefixbefore>; +def _include_with_prefix_before : Separate<["--"], "include-with-prefix-before">, Alias<iwithprefixbefore>; +def _include_with_prefix_EQ : Joined<["--"], "include-with-prefix=">, Alias<iwithprefix>; +def _include_with_prefix : Separate<["--"], "include-with-prefix">, Alias<iwithprefix>; +def _include_EQ : Joined<["--"], "include=">, Alias<include_>; +def _language_EQ : Joined<["--"], "language=">, Alias<x>; +def _language : Separate<["--"], "language">, Alias<x>; +def _library_directory_EQ : Joined<["--"], "library-directory=">, Alias<L>; +def _library_directory : Separate<["--"], "library-directory">, Alias<L>; +def _machine__EQ : Joined<["--"], "machine-=">, Alias<m_Joined>; +def _machine_ : Joined<["--"], "machine-">, Alias<m_Joined>; +def _machine_EQ : Joined<["--"], "machine=">, Alias<m_Joined>; +def _machine : Separate<["--"], "machine">, Alias<m_Joined>; +def _no_line_commands : Flag<["--"], "no-line-commands">, Alias<P>; +def _no_standard_includes : Flag<["--"], "no-standard-includes">, Alias<nostdinc>; +def _no_standard_libraries : Flag<["--"], "no-standard-libraries">, Alias<nostdlib>; +def _no_undefined : Flag<["--"], "no-undefined">, Flags<[LinkerInput]>; +def _no_warnings : Flag<["--"], "no-warnings">, Alias<w>; +def _optimize_EQ : Joined<["--"], "optimize=">, Alias<O>; +def _optimize : Flag<["--"], "optimize">, Alias<O>; +def _output_class_directory_EQ : Joined<["--"], "output-class-directory=">, Alias<foutput_class_dir_EQ>; +def _output_class_directory : Separate<["--"], "output-class-directory">, Alias<foutput_class_dir_EQ>; +def _output_EQ : Joined<["--"], "output=">, Alias<o>; +def _output : Separate<["--"], "output">, Alias<o>; +def _param : Separate<["--"], "param">; +def _param_EQ : Joined<["--"], "param=">, Alias<_param>; +def _prefix_EQ : Joined<["--"], "prefix=">, Alias<B>; +def _prefix : Separate<["--"], "prefix">, Alias<B>; +def _preprocess : Flag<["--"], "preprocess">, Alias<E>; +def _print_diagnostic_categories : Flag<["--"], "print-diagnostic-categories">; +def _print_file_name : Separate<["--"], "print-file-name">, Alias<print_file_name_EQ>; +def _print_missing_file_dependencies : Flag<["--"], "print-missing-file-dependencies">, Alias<MG>; +def _print_prog_name : Separate<["--"], "print-prog-name">, Alias<print_prog_name_EQ>; +def _profile_blocks : Flag<["--"], "profile-blocks">, Alias<a>; +def _profile : Flag<["--"], "profile">, Alias<p>; +def _resource_EQ : Joined<["--"], "resource=">, Alias<fcompile_resource_EQ>; +def _resource : Separate<["--"], "resource">, Alias<fcompile_resource_EQ>; +def _rtlib : Separate<["--"], "rtlib">, Alias<rtlib_EQ>; +def _serialize_diags : Separate<["-", "--"], "serialize-diagnostics">, Flags<[DriverOption]>, HelpText<"Serialize compiler diagnostics to a file">; -def _shared : Flag<"--shared">, Alias<shared>; -def _signed_char : Flag<"--signed-char">, Alias<fsigned_char>; -def _specs_EQ : Joined<"--specs=">, Alias<specs_EQ>; -def _specs : Separate<"--specs">, Alias<specs_EQ>; -def _static : Flag<"--static">, Alias<static>; -def _std_EQ : Joined<"--std=">, Alias<std_EQ>; -def _std : Separate<"--std">, Alias<std_EQ>; -def _stdlib_EQ : Joined<"--stdlib=">, Alias<stdlib_EQ>; -def _stdlib : Separate<"--stdlib">, Alias<stdlib_EQ>; -def _sysroot_EQ : Joined<"--sysroot=">; -def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>; -def _target_help : Flag<"--target-help">; -def _trace_includes : Flag<"--trace-includes">, Alias<H>; -def _traditional_cpp : Flag<"--traditional-cpp">, Alias<traditional_cpp>; -def _traditional : Flag<"--traditional">, Alias<traditional>; -def _trigraphs : Flag<"--trigraphs">, Alias<trigraphs>; -def _undefine_macro_EQ : Joined<"--undefine-macro=">, Alias<U>; -def _undefine_macro : Separate<"--undefine-macro">, Alias<U>; -def _unsigned_char : Flag<"--unsigned-char">, Alias<funsigned_char>; -def _user_dependencies : Flag<"--user-dependencies">, Alias<MM>; -def _verbose : Flag<"--verbose">, Alias<v>; -def _version : Flag<"--version">, Flags<[CC1Option]>; -def _warn__EQ : Joined<"--warn-=">, Alias<W_Joined>; -def _warn_ : Joined<"--warn-">, Alias<W_Joined>; -def _write_dependencies : Flag<"--write-dependencies">, Alias<MD>; -def _write_user_dependencies : Flag<"--write-user-dependencies">, Alias<MMD>; -def _ : Joined<"--">, Flags<[Unsupported]>; -def mieee_rnd_near : Flag<"-mieee-rnd-near">, Group<m_hexagon_Features_Group>; -def serialize_diags : Separate<"-serialize-diagnostics">, Alias<_serialize_diags>; +// We give --version different semantics from -version. +def _version : Flag<["--"], "version">, Flags<[CC1Option]>; +def _signed_char : Flag<["--"], "signed-char">, Alias<fsigned_char>; +def _std : Separate<["--"], "std">, Alias<std_EQ>; +def _stdlib : Separate<["--"], "stdlib">, Alias<stdlib_EQ>; +def _sysroot_EQ : Joined<["--"], "sysroot=">; +def _sysroot : Separate<["--"], "sysroot">, Alias<_sysroot_EQ>; +def _target_help : Flag<["--"], "target-help">; +def _trace_includes : Flag<["--"], "trace-includes">, Alias<H>; +def _undefine_macro_EQ : Joined<["--"], "undefine-macro=">, Alias<U>; +def _undefine_macro : Separate<["--"], "undefine-macro">, Alias<U>; +def _unsigned_char : Flag<["--"], "unsigned-char">, Alias<funsigned_char>; +def _user_dependencies : Flag<["--"], "user-dependencies">, Alias<MM>; +def _verbose : Flag<["--"], "verbose">, Alias<v>; +def _warn__EQ : Joined<["--"], "warn-=">, Alias<W_Joined>; +def _warn_ : Joined<["--"], "warn-">, Alias<W_Joined>; +def _write_dependencies : Flag<["--"], "write-dependencies">, Alias<MD>; +def _write_user_dependencies : Flag<["--"], "write-user-dependencies">, Alias<MMD>; +def _ : Joined<["--"], "">, Flags<[Unsupported]>; +def mieee_rnd_near : Flag<["-"], "mieee-rnd-near">, Group<m_hexagon_Features_Group>; // Special internal option to handle -Xlinker --no-demangle. -def Z_Xlinker__no_demangle : Flag<"-Z-Xlinker-no-demangle">, +def Z_Xlinker__no_demangle : Flag<["-"], "Z-Xlinker-no-demangle">, Flags<[Unsupported, NoArgumentUnused]>; // Special internal option to allow forwarding arbitrary arguments to linker. -def Zlinker_input : Separate<"-Zlinker-input">, +def Zlinker_input : Separate<["-"], "Zlinker-input">, Flags<[Unsupported, NoArgumentUnused]>; // Reserved library options. -def Z_reserved_lib_stdcxx : Flag<"-Z-reserved-lib-stdc++">, +def Z_reserved_lib_stdcxx : Flag<["-"], "Z-reserved-lib-stdc++">, Flags<[LinkerInput, NoArgumentUnused, Unsupported]>, Group<reserved_lib_Group>; -def Z_reserved_lib_cckext : Flag<"-Z-reserved-lib-cckext">, +def Z_reserved_lib_cckext : Flag<["-"], "Z-reserved-lib-cckext">, Flags<[LinkerInput, NoArgumentUnused, Unsupported]>, Group<reserved_lib_Group>; include "CC1Options.td" diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Tool.h b/contrib/llvm/tools/clang/include/clang/Driver/Tool.h index 8822d7b..c62e756 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Tool.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Tool.h @@ -55,8 +55,8 @@ public: /// driver add an additional "command failed" diagnostic on failures. virtual bool hasGoodDiagnostics() const { return false; } - /// ConstructJob - Construct jobs to perform the action \arg JA, - /// writing to \arg Output and with \arg Inputs. + /// ConstructJob - Construct jobs to perform the action \p JA, + /// writing to \p Output and with \p Inputs. /// /// \param TCArgs - The argument list for this toolchain, with any /// tool chain specific translations applied. diff --git a/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h index ab417bb..509e08d 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h @@ -85,6 +85,10 @@ public: StringRef getPlatform() const { return Triple.getVendorName(); } StringRef getOS() const { return Triple.getOSName(); } + /// \brief Provide the default architecture name (as expected by -arch) for + /// this toolchain. Note t + std::string getDefaultUniversalArchName() const; + std::string getTripleString() const { return Triple.getTriple(); } @@ -107,15 +111,15 @@ public: return 0; } - /// SelectTool - Choose a tool to use to handle the action \arg JA with the - /// given \arg Inputs. + /// SelectTool - Choose a tool to use to handle the action \p JA with the + /// given \p Inputs. virtual Tool &SelectTool(const Compilation &C, const JobAction &JA, const ActionList &Inputs) const = 0; // Helper methods std::string GetFilePath(const char *Name) const; - std::string GetProgramPath(const char *Name, bool WantFile = false) const; + std::string GetProgramPath(const char *Name) const; // Platform defaults information @@ -144,6 +148,10 @@ public: /// IsObjCDefaultSynthPropertiesDefault - Does this tool chain enable /// -fobjc-default-synthesize-properties by default. virtual bool IsObjCDefaultSynthPropertiesDefault() const { return false; } + + /// IsEncodeExtendedBlockSignatureDefault - Does this tool chain enable + /// -fencode-extended-block-signature by default. + virtual bool IsEncodeExtendedBlockSignatureDefault() const { return false; } /// IsObjCNonFragileABIDefault - Does this tool chain set /// -fobjc-nonfragile-abi by default. @@ -166,16 +174,15 @@ public: /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables /// by default. - virtual bool IsUnwindTablesDefault() const = 0; + virtual bool IsUnwindTablesDefault() const; - /// GetDefaultRelocationModel - Return the LLVM name of the default - /// relocation model for this tool chain. - virtual const char *GetDefaultRelocationModel() const = 0; + /// \brief Test whether this toolchain defaults to PIC. + virtual bool isPICDefault() const = 0; - /// GetForcedPicModel - Return the LLVM name of the forced PIC model - /// for this tool chain, or 0 if this tool chain does not force a - /// particular PIC mode. - virtual const char *GetForcedPicModel() const = 0; + /// \brief Tests whether this toolchain forces its default for PIC or non-PIC. + /// If this returns true, any PIC related flags should be ignored and instead + /// the result of \c isPICDefault() is used exclusively. + virtual bool isPICDefaultForced() const = 0; /// SupportsProfiling - Does this tool chain support -pg. virtual bool SupportsProfiling() const { return true; } @@ -183,8 +190,8 @@ public: /// Does this tool chain support Objective-C garbage collection. virtual bool SupportsObjCGC() const { return true; } - /// Does this tool chain support Objective-C ARC. - virtual bool SupportsObjCARC() const { return true; } + /// Complain if this tool chain doesn't support Objective-C ARC. + virtual void CheckObjCARC() const {} /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf /// compile unit information. @@ -252,6 +259,13 @@ public: /// for kernel extensions (Darwin-specific). virtual void AddCCKextLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const; + + /// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets + /// global flags for unsafe floating point math, add it and return true. + /// + /// This checks for presence of the -ffast-math or -funsafe-math flags. + virtual bool AddFastMathRuntimeIfAvailable(const ArgList &Args, + ArgStringList &CmdArgs) const; }; } // end namespace driver diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Types.h b/contrib/llvm/tools/clang/include/clang/Driver/Types.h index 3dea471..d28ca88 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Types.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Types.h @@ -59,10 +59,6 @@ namespace types { /// isAcceptedByClang - Can clang handle this input type. bool isAcceptedByClang(ID Id); - /// isOnlyAcceptedByClang - Is clang the only compiler that can handle this - /// input type. - bool isOnlyAcceptedByClang(ID Id); - /// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers). bool isCXX(ID Id); diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h index 144b796..5e409bd 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h @@ -19,11 +19,13 @@ #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Lex/ModuleLoader.h" #include "clang/Lex/PreprocessingRecord.h" +#include "clang/Lex/HeaderSearchOptions.h" #include "clang/AST/ASTContext.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/TargetOptions.h" #include "clang-c/Index.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/OwningPtr.h" @@ -56,21 +58,27 @@ class Preprocessor; class SourceManager; class TargetInfo; class ASTFrontendAction; +class ASTDeserializationListener; /// \brief Utility class for loading a ASTContext from an AST file. /// class ASTUnit : public ModuleLoader { private: - IntrusiveRefCntPtr<LangOptions> LangOpts; - IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; - IntrusiveRefCntPtr<FileManager> FileMgr; - IntrusiveRefCntPtr<SourceManager> SourceMgr; - OwningPtr<HeaderSearch> HeaderInfo; - IntrusiveRefCntPtr<TargetInfo> Target; - IntrusiveRefCntPtr<Preprocessor> PP; - IntrusiveRefCntPtr<ASTContext> Ctx; + IntrusiveRefCntPtr<LangOptions> LangOpts; + IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; + IntrusiveRefCntPtr<FileManager> FileMgr; + IntrusiveRefCntPtr<SourceManager> SourceMgr; + OwningPtr<HeaderSearch> HeaderInfo; + IntrusiveRefCntPtr<TargetInfo> Target; + IntrusiveRefCntPtr<Preprocessor> PP; + IntrusiveRefCntPtr<ASTContext> Ctx; + IntrusiveRefCntPtr<TargetOptions> TargetOpts; + IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts; ASTReader *Reader; + struct ASTWriterData; + OwningPtr<ASTWriterData> WriterData; + FileSystemOptions FileSystemOpts; /// \brief The AST consumer that received information about the translation @@ -85,13 +93,6 @@ private: /// LoadFromCommandLine available. IntrusiveRefCntPtr<CompilerInvocation> Invocation; - /// \brief The set of target features. - /// - /// FIXME: each time we reparse, we need to restore the set of target - /// features from this vector, because TargetInfo::CreateTargetInfo() - /// mangles the target options in place. Yuck! - std::vector<std::string> TargetFeatures; - // OnlyLocalDecls - when true, walking this AST should only visit declarations // that come from the AST itself, not from included precompiled headers. // FIXME: This is temporary; eventually, CIndex will always do this. @@ -374,8 +375,8 @@ private: /// \brief Clear out and deallocate void ClearCachedCompletionResults(); - ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT - ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT + ASTUnit(const ASTUnit &) LLVM_DELETED_FUNCTION; + void operator=(const ASTUnit &) LLVM_DELETED_FUNCTION; explicit ASTUnit(bool MainFileIsAST); @@ -466,7 +467,11 @@ public: const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } - const std::string &getOriginalSourceFileName(); + StringRef getOriginalSourceFileName() { + return OriginalSourceFile; + } + + ASTDeserializationListener *getDeserializationListener(); /// \brief Add a temporary file that the ASTUnit depends on. /// @@ -515,7 +520,7 @@ public: void addFileLevelDecl(Decl *D); /// \brief Get the decls that are contained in a file in the Offset/Length - /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of + /// range. \p Length can be 0 to indicate a point at \p Offset instead of /// a range. void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, SmallVectorImpl<Decl *> &Decls); @@ -542,14 +547,14 @@ public: /// \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 + /// \brief If \p Loc is a loaded location from the preamble, returns /// the corresponding local location of the main file, otherwise it returns - /// \arg Loc. + /// \p Loc. SourceLocation mapLocationFromPreamble(SourceLocation Loc); - /// \brief If \arg Loc is a local location of the main file but inside the + /// \brief If \p 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. + /// preamble, otherwise it returns \p Loc. SourceLocation mapLocationToPreamble(SourceLocation Loc); bool isInPreambleFileID(SourceLocation Loc); @@ -557,13 +562,13 @@ public: SourceLocation getStartOfMainFileID(); SourceLocation getEndOfPreambleFileID(); - /// \brief \see mapLocationFromPreamble. + /// \see mapLocationFromPreamble. SourceRange mapRangeFromPreamble(SourceRange R) { return SourceRange(mapLocationFromPreamble(R.getBegin()), mapLocationFromPreamble(R.getEnd())); } - /// \brief \see mapLocationToPreamble. + /// \see mapLocationToPreamble. SourceRange mapRangeToPreamble(SourceRange R) { return SourceRange(mapLocationToPreamble(R.getBegin()), mapLocationToPreamble(R.getEnd())); @@ -607,6 +612,29 @@ public: return CachedCompletionResults.size(); } + /// \brief Returns an iterator range for the local preprocessing entities + /// of the local Preprocessor, if this is a parsed source file, or the loaded + /// preprocessing entities of the primary module if this is an AST file. + std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> + getLocalPreprocessingEntities() const; + + /// \brief Type for a function iterating over a number of declarations. + /// \returns true to continue iteration and false to abort. + typedef bool (*DeclVisitorFn)(void *context, const Decl *D); + + /// \brief Iterate over local declarations (locally parsed if this is a parsed + /// source file or the loaded declarations of the primary module if this is an + /// AST file). + /// \returns true if the iteration was complete or false if it was aborted. + bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn); + + /// \brief Get the PCH file if one was included. + const FileEntry *getPCHFile(); + + /// \brief Returns true if the ASTUnit was constructed from a serialized + /// module file. + bool isModuleFile(); + llvm::MemoryBuffer *getBufferForFile(StringRef Filename, std::string *ErrorStr = 0); @@ -679,7 +707,7 @@ public: /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit /// mainly to allow the caller to see the diagnostics. /// This will only receive an ASTUnit if a new one was created. If an already - /// created ASTUnit was passed in \param Unit then the caller can check that. + /// created ASTUnit was passed in \p Unit then the caller can check that. /// static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, @@ -750,6 +778,7 @@ public: bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false, bool UserFilesAreVolatile = false, + bool ForSerialization = false, OwningPtr<ASTUnit> *ErrAST = 0); /// \brief Reparse the source files using the same command-line options that @@ -792,8 +821,9 @@ public: /// \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(StringRef File); + /// \returns true if there was a file error or false if the save was + /// successful. + bool Save(StringRef File); /// \brief Serialize this translation unit with the given output stream. /// diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/AnalyzerOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/AnalyzerOptions.h deleted file mode 100644 index 4e489fe..0000000 --- a/contrib/llvm/tools/clang/include/clang/Frontend/AnalyzerOptions.h +++ /dev/null @@ -1,135 +0,0 @@ -//===--- AnalyzerOptions.h - Analysis Engine Options ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header contains the structures necessary for a front-end to specify -// various analyses. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_FRONTEND_ANALYZEROPTIONS_H -#define LLVM_CLANG_FRONTEND_ANALYZEROPTIONS_H - -#include <string> -#include <vector> - -namespace clang { -class ASTConsumer; -class DiagnosticsEngine; -class Preprocessor; -class LangOptions; - -/// Analysis - Set of available source code analyses. -enum Analyses { -#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME, -#include "clang/Frontend/Analyses.def" -NumAnalyses -}; - -/// AnalysisStores - Set of available analysis store models. -enum AnalysisStores { -#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model, -#include "clang/Frontend/Analyses.def" -NumStores -}; - -/// AnalysisConstraints - Set of available constraint models. -enum AnalysisConstraints { -#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model, -#include "clang/Frontend/Analyses.def" -NumConstraints -}; - -/// AnalysisDiagClients - Set of available diagnostic clients for rendering -/// analysis results. -enum AnalysisDiagClients { -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) PD_##NAME, -#include "clang/Frontend/Analyses.def" -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 -}; - -/// AnalysisIPAMode - Set of inter-procedural modes. -enum AnalysisIPAMode { -#define ANALYSIS_IPA(NAME, CMDFLAG, DESC) NAME, -#include "clang/Frontend/Analyses.def" -NumIPAModes -}; - -/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics. -enum AnalysisInliningMode { -#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME, -#include "clang/Frontend/Analyses.def" -NumInliningModes -}; - -class AnalyzerOptions { -public: - /// \brief Pair of checker name and enable/disable. - std::vector<std::pair<std::string, bool> > CheckersControlList; - AnalysisStores AnalysisStoreOpt; - AnalysisConstraints AnalysisConstraintsOpt; - AnalysisDiagClients AnalysisDiagOpt; - AnalysisPurgeMode AnalysisPurgeOpt; - AnalysisIPAMode IPAMode; - std::string AnalyzeSpecificFunction; - unsigned MaxNodes; - unsigned MaxLoop; - unsigned ShowCheckerHelp : 1; - unsigned AnalyzeAll : 1; - unsigned AnalyzerDisplayProgress : 1; - unsigned AnalyzeNestedBlocks : 1; - unsigned EagerlyAssume : 1; - unsigned TrimGraph : 1; - unsigned VisualizeEGDot : 1; - unsigned VisualizeEGUbi : 1; - unsigned UnoptimizedCFG : 1; - unsigned CFGAddImplicitDtors : 1; - unsigned EagerlyTrimEGraph : 1; - unsigned PrintStats : 1; - unsigned NoRetryExhausted : 1; - unsigned InlineMaxStackDepth; - unsigned InlineMaxFunctionSize; - AnalysisInliningMode InliningMode; - -public: - AnalyzerOptions() { - AnalysisStoreOpt = RegionStoreModel; - AnalysisConstraintsOpt = RangeConstraintsModel; - AnalysisDiagOpt = PD_HTML; - AnalysisPurgeOpt = PurgeStmt; - IPAMode = Inlining; - ShowCheckerHelp = 0; - AnalyzeAll = 0; - AnalyzerDisplayProgress = 0; - AnalyzeNestedBlocks = 0; - EagerlyAssume = 0; - TrimGraph = 0; - VisualizeEGDot = 0; - VisualizeEGUbi = 0; - UnoptimizedCFG = 0; - CFGAddImplicitDtors = 0; - EagerlyTrimEGraph = 0; - PrintStats = 0; - NoRetryExhausted = 0; - // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls). - InlineMaxStackDepth = 5; - InlineMaxFunctionSize = 200; - InliningMode = NoRedundancy; - } -}; - -} - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def new file mode 100644 index 0000000..558e6f1 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def @@ -0,0 +1,132 @@ +//===--- CodeGenOptions.def - Code generation 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 code generation options. Users of this file +// must define the CODEGENOPT macro to make use of this information. +// Optionally, the user may also define ENUM_CODEGENOPT (for options +// that have enumeration type and VALUE_CODEGENOPT is a code +// generation option that describes a value rather than a flag. +// +//===----------------------------------------------------------------------===// +#ifndef CODEGENOPT +# error Define the CODEGENOPT macro to handle language options +#endif + +#ifndef VALUE_CODEGENOPT +# define VALUE_CODEGENOPT(Name, Bits, Default) \ +CODEGENOPT(Name, Bits, Default) +#endif + +#ifndef ENUM_CODEGENOPT +# define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ +CODEGENOPT(Name, Bits, Default) +#endif + +CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm. +CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe. +CODEGENOPT(CUDAIsDevice , 1, 0) ///< Set when compiling for CUDA device. +CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors. +CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker + ///< aliases to base ctors when possible. +CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled. +CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabled. +CODEGENOPT(DisableLLVMOpts , 1, 0) ///< Don't run any optimizations, for use in + ///< getting .bc files that correspond to the + ///< internal state before optimizations are + ///< done. +CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled. +CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls. +CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what + ///< Decl* various IR entities came from. + ///< Only useful when running CodeGen as a + ///< subroutine. +CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA. +CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO. +CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata. +CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables + ///< are required. +CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled. +CODEGENOPT(HiddenWeakVTables , 1, 0) ///< Emit weak vtables, RTTI, and thunks with + ///< hidden visibility. +CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is + ///< enabled. +CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. +CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to + ///< be generated. +CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants. +CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled. +CODEGENOPT(NoDwarf2CFIAsm , 1, 0) ///< Set when -fno-dwarf2-cfi-asm is enabled. +CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is + ///< enabled. +CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled. +CODEGENOPT(NoGlobalMerge , 1, 0) ///< Set when -mno-global-merge is enabled. +CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. +CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf. +CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled. + ///< Disables use of the inline keyword. +CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN. +CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss. +/// \brief Method of Objective-C dispatch to use. +ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy) +CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is + ///< enabled. +VALUE_CODEGENOPT(OptimizationLevel, 3, 0) ///< The -O[0-4] option specified. +VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified. +CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. +CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. +CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. +CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled. +CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float. +CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition. +CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled. +CODEGENOPT(UnitAtATime , 1, 1) ///< Unused. For mirroring GCC optimization + ///< selection. +CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. +CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns. +CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables. + + /// Attempt to use register sized accesses to bit-fields in structures, when + /// possible. +CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0) + +CODEGENOPT(VerifyModule , 1, 1) ///< Control whether the module should be run + ///< through the LLVM Verifier. + +CODEGENOPT(StackRealignment , 1, 0) ///< Control whether to permit stack + ///< realignment. +CODEGENOPT(UseInitArray , 1, 0) ///< Control whether to use .init_array or + ///< .ctors. +VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack + ///< alignment, if not 0. +CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information + ///< in debug info. + +/// The user specified number of registers to be used for integral arguments, +/// or 0 if unspecified. +VALUE_CODEGENOPT(NumRegisterParameters, 32, 0) + +/// The run-time penalty for bounds checking, or 0 to disable. +VALUE_CODEGENOPT(BoundsChecking, 8, 0) + +/// The lower bound for a buffer to be considered for stack protection. +VALUE_CODEGENOPT(SSPBufferSize, 32, 0) + +/// The kind of generated debug info. +ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 2, NoDebugInfo) + +/// The kind of inlining to perform. +ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining) + +/// The default TLS model to use. +ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel) + +#undef CODEGENOPT +#undef ENUM_CODEGENOPT +#undef VALUE_CODEGENOPT + diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h index 3e34093..3567187 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h @@ -19,9 +19,23 @@ namespace clang { +/// \brief Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure +/// that this large collection of bitfields is a trivial class type. +class CodeGenOptionsBase { +public: +#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits; +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) +#include "clang/Frontend/CodeGenOptions.def" + +protected: +#define CODEGENOPT(Name, Bits, Default) +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) unsigned Name : Bits; +#include "clang/Frontend/CodeGenOptions.def" +}; + /// CodeGenOptions - Track various options which control how the code /// is optimized and passed to the backend. -class CodeGenOptions { +class CodeGenOptions : public CodeGenOptionsBase { public: enum InliningMethod { NoInlining, // Perform no inlining whatsoever. @@ -51,86 +65,6 @@ public: LocalExecTLSModel }; - 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. - unsigned DataSections : 1; ///< Set when -fdata-sections is enabled. - unsigned DisableFPElim : 1; ///< Set when -fomit-frame-pointer is enabled. - unsigned DisableLLVMOpts : 1; ///< Don't run any optimizations, for use in - ///< getting .bc files that correspond to the - ///< internal state before optimizations are - ///< done. - unsigned DisableRedZone : 1; ///< Set when -mno-red-zone is enabled. - unsigned DisableTailCalls : 1; ///< Do not emit tail calls. - unsigned EmitDeclMetadata : 1; ///< Emit special metadata indicating what - ///< Decl* various IR entities came from. Only - ///< useful when running CodeGen as a - ///< subroutine. - unsigned EmitGcovArcs : 1; ///< Emit coverage data files, aka. GCDA. - unsigned EmitGcovNotes : 1; ///< Emit coverage "notes" files, aka GCNO. - unsigned EmitOpenCLArgMetadata : 1; ///< Emit OpenCL kernel arg metadata. - unsigned EmitMicrosoftInlineAsm : 1; ///< Enable emission of MS-style inline - ///< assembly. - unsigned ForbidGuardVariables : 1; ///< Issue errors if C++ guard variables - ///< are required. - unsigned FunctionSections : 1; ///< Set when -ffunction-sections is enabled. - unsigned HiddenWeakTemplateVTables : 1; ///< Emit weak vtables and RTTI for - ///< template classes with hidden visibility - unsigned HiddenWeakVTables : 1; ///< Emit weak vtables, RTTI, and thunks with - ///< hidden visibility. - unsigned InstrumentFunctions : 1; ///< Set when -finstrument-functions is - ///< enabled. - unsigned InstrumentForProfiling : 1; ///< Set when -pg is enabled. - unsigned LessPreciseFPMAD : 1; ///< Enable less precise MAD instructions to - ///< be generated. - unsigned MergeAllConstants : 1; ///< Merge identical constants. - unsigned NoCommon : 1; ///< Set when -fno-common or C++ is enabled. - unsigned NoDwarf2CFIAsm : 1; ///< Set when -fno-dwarf2-cfi-asm is enabled. - unsigned NoDwarfDirectoryAsm : 1; ///< Set when -fno-dwarf-directory-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 NoInline : 1; ///< Set when -fno-inline is enabled. Disables - ///< use of the inline keyword. - unsigned NoNaNsFPMath : 1; ///< Assume FP arguments, results not NaN. - unsigned NoZeroInitializedInBSS : 1; ///< -fno-zero-initialized-in-bss. - unsigned ObjCDispatchMethod : 2; ///< Method of Objective-C dispatch to use. - unsigned OmitLeafFramePointer : 1; ///< Set when -momit-leaf-frame-pointer is - ///< enabled. - unsigned OptimizationLevel : 3; ///< The -O[0-4] option specified. - unsigned OptimizeSize : 2; ///< If -Os (==1) or -Oz (==2) is specified. - unsigned RelaxAll : 1; ///< Relax all machine code instructions. - unsigned RelaxedAliasing : 1; ///< Set when -fno-strict-aliasing is enabled. - unsigned SaveTempLabels : 1; ///< Save temporary labels. - unsigned SimplifyLibCalls : 1; ///< Set when -fbuiltin is enabled. - unsigned SoftFloat : 1; ///< -soft-float. - unsigned StrictEnums : 1; ///< Optimize based on strict enum definition. - unsigned TimePasses : 1; ///< Set when -ftime-report is enabled. - unsigned UnitAtATime : 1; ///< Unused. For mirroring GCC optimization - ///< selection. - unsigned UnrollLoops : 1; ///< Control whether loops are unrolled. - unsigned UnsafeFPMath : 1; ///< Allow unsafe floating point optzns. - unsigned UnwindTables : 1; ///< Emit unwind tables. - - /// Attempt to use register sized accesses to bit-fields in structures, when - /// possible. - unsigned UseRegisterSizedBitfieldAccess : 1; - - unsigned VerifyModule : 1; ///< Control whether the module should be run - ///< through the LLVM Verifier. - - unsigned StackRealignment : 1; ///< Control whether to permit stack - ///< realignment. - unsigned UseInitArray : 1; ///< Control whether to use .init_array or - ///< .ctors. - unsigned StackAlignment; ///< Overrides default stack alignment, - ///< if not 0. - /// The code model to use (-mcmodel). std::string CodeModel; @@ -144,9 +78,6 @@ public: /// The string to embed in debug information as the current working directory. std::string DebugCompilationDir; - /// The kind of generated debug info. - DebugInfoKind DebugInfo; - /// The string to embed in the debug information for the compile unit, if /// non-empty. std::string DwarfDebugFlags; @@ -160,9 +91,6 @@ public: /// The name of the bitcode file to link before optzns. std::string LinkBitcodeFile; - /// The kind of inlining to perform. - InliningMethod Inlining; - /// The user provided name for the "main file", if non-empty. This is useful /// in situations where the input file name does not match the original input /// file, for example with -save-temps. @@ -178,79 +106,21 @@ public: /// A list of command-line options to forward to the LLVM backend. std::vector<std::string> BackendOptions; - /// The user specified number of registers to be used for integral arguments, - /// or 0 if unspecified. - unsigned NumRegisterParameters; - - /// The run-time penalty for bounds checking, or 0 to disable. - unsigned char BoundsChecking; - - /// The default TLS model to use. - TLSModel DefaultTLSModel; - public: + // Define accessors/mutators for code generation options of enumeration type. +#define CODEGENOPT(Name, Bits, Default) +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ + Type get##Name() const { return static_cast<Type>(Name); } \ + void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } +#include "clang/Frontend/CodeGenOptions.def" + CodeGenOptions() { - AsmVerbose = 0; - CUDAIsDevice = 0; - CXAAtExit = 1; - CXXCtorDtorAliases = 0; - DataSections = 0; - DisableFPElim = 0; - DisableLLVMOpts = 0; - DisableRedZone = 0; - DisableTailCalls = 0; - EmitDeclMetadata = 0; - EmitGcovArcs = 0; - EmitGcovNotes = 0; - EmitOpenCLArgMetadata = 0; - EmitMicrosoftInlineAsm = 0; - ForbidGuardVariables = 0; - FunctionSections = 0; - HiddenWeakTemplateVTables = 0; - HiddenWeakVTables = 0; - InstrumentFunctions = 0; - InstrumentForProfiling = 0; - LessPreciseFPMAD = 0; - MergeAllConstants = 1; - NoCommon = 0; - NoDwarf2CFIAsm = 0; - NoImplicitFloat = 0; - NoInfsFPMath = 0; - NoInline = 0; - NoNaNsFPMath = 0; - NoZeroInitializedInBSS = 0; - NumRegisterParameters = 0; - ObjCAutoRefCountExceptions = 0; - ObjCDispatchMethod = Legacy; - OmitLeafFramePointer = 0; - OptimizationLevel = 0; - OptimizeSize = 0; - RelaxAll = 0; - RelaxedAliasing = 0; - SaveTempLabels = 0; - SimplifyLibCalls = 1; - SoftFloat = 0; - StrictEnums = 0; - TimePasses = 0; - UnitAtATime = 1; - UnrollLoops = 0; - UnsafeFPMath = 0; - UnwindTables = 0; - UseRegisterSizedBitfieldAccess = 0; - VerifyModule = 1; - StackRealignment = 0; - StackAlignment = 0; - BoundsChecking = 0; - UseInitArray = 0; +#define CODEGENOPT(Name, Bits, Default) Name = Default; +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ + set##Name(Default); +#include "clang/Frontend/CodeGenOptions.def" - DebugInfo = NoDebugInfo; - Inlining = NoInlining; RelocationModel = "pic"; - DefaultTLSModel = GeneralDynamicTLSModel; - } - - ObjCDispatchMethodKind getObjCDispatchMethod() const { - return ObjCDispatchMethodKind(ObjCDispatchMethod); } }; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h index b28e103..2f3dc3f 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/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/ModuleLoader.h" #include "llvm/ADT/ArrayRef.h" @@ -130,8 +131,8 @@ class CompilerInstance : public ModuleLoader { /// The list of active output files. std::list<OutputFile> OutputFiles; - void operator=(const CompilerInstance &); // DO NOT IMPLEMENT - CompilerInstance(const CompilerInstance&); // DO NOT IMPLEMENT + CompilerInstance(const CompilerInstance &) LLVM_DELETED_FUNCTION; + void operator=(const CompilerInstance &) LLVM_DELETED_FUNCTION; public: CompilerInstance(); ~CompilerInstance(); @@ -189,10 +190,7 @@ public: /// @name Forwarding Methods /// { - AnalyzerOptions &getAnalyzerOpts() { - return Invocation->getAnalyzerOpts(); - } - const AnalyzerOptions &getAnalyzerOpts() const { + AnalyzerOptionsRef getAnalyzerOpts() { return Invocation->getAnalyzerOpts(); } @@ -393,7 +391,7 @@ public: ASTConsumer *takeASTConsumer() { return Consumer.take(); } /// setASTConsumer - Replace the current AST consumer; the compiler instance - /// takes ownership of \arg Value. + /// takes ownership of \p Value. void setASTConsumer(ASTConsumer *Value); /// } @@ -433,7 +431,7 @@ public: } /// setCodeCompletionConsumer - Replace the current code completion consumer; - /// the compiler instance takes ownership of \arg Value. + /// the compiler instance takes ownership of \p Value. void setCodeCompletionConsumer(CodeCompleteConsumer *Value); /// } @@ -488,7 +486,7 @@ public: /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter. /// - /// The \arg Argc and \arg Argv arguments are used only for logging purposes, + /// The \p Argc and \p Argv arguments are used only for logging purposes, /// when the diagnostic options indicate that the compiler should output /// logging information. /// @@ -498,8 +496,7 @@ public: /// 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. + /// diagnostic object contains a reference to these options. /// /// \param Client If non-NULL, a diagnostic client that will be /// attached to (and, then, owned by) the returned DiagnosticsEngine @@ -510,7 +507,7 @@ public: /// /// \return The new object on success, or null on failure. static IntrusiveRefCntPtr<DiagnosticsEngine> - createDiagnostics(const DiagnosticOptions &Opts, int Argc, + createDiagnostics(DiagnosticOptions *Opts, int Argc, const char* const *Argv, DiagnosticConsumer *Client = 0, bool ShouldOwnClient = true, @@ -534,7 +531,6 @@ public: /// context. void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation, - bool DisableStatCache, bool AllowPCHWithCompilerErrors, void *DeserializationListener); @@ -544,7 +540,6 @@ public: static ExternalASTSource * createPCHExternalASTSource(StringRef Path, const std::string &Sysroot, bool DisablePCHValidation, - bool DisableStatCache, bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, void *DeserializationListener, bool Preamble); @@ -555,8 +550,7 @@ public: void createCodeCompletionConsumer(); /// Create a code completion consumer to print code completion results, at - /// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg - /// OS. + /// \p Filename, \p Line, and \p Column, to the given output stream \p OS. static CodeCompleteConsumer * createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename, unsigned Line, unsigned Column, @@ -596,15 +590,15 @@ public: /// 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 and \arg UseTemporary + /// If \p OutputPath is empty, then createOutputFile will derive an output + /// path location as \p BaseInput, with any suffix removed, and \p Extension + /// appended. If \p OutputPath is not stdout and \p UseTemporary /// is true, createOutputFile will create a new temporary file that must be - /// renamed to OutputPath in the end. + /// renamed to \p OutputPath in the end. /// /// \param OutputPath - If given, the path to the output file. /// \param Error [out] - On failure, the error message. - /// \param BaseInput - If \arg OutputPath is empty, the input path name to use + /// \param BaseInput - If \p OutputPath is empty, the input path name to use /// for deriving the output path. /// \param Extension - The extension to use for derived output names. /// \param Binary - The mode to open the file in. @@ -613,7 +607,7 @@ public: /// 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 CreateMissingDirectories - When \arg UseTemporary is true, create + /// \param CreateMissingDirectories - When \p UseTemporary is true, create /// missing directories in the output path. /// \param ResultPathName [out] - If given, the result path name will be /// stored here on success. @@ -637,15 +631,13 @@ public: /// as the main file. /// /// \return True on success. - bool InitializeSourceManager(StringRef InputFile, - SrcMgr::CharacteristicKind Kind = SrcMgr::C_User); + bool InitializeSourceManager(const FrontendInputFile &Input); /// InitializeSourceManager - Initialize the source manager to set InputFile /// as the main file. /// /// \return True on success. - static bool InitializeSourceManager(StringRef InputFile, - SrcMgr::CharacteristicKind Kind, + static bool InitializeSourceManager(const FrontendInputFile &Input, DiagnosticsEngine &Diags, FileManager &FileMgr, SourceManager &SourceMgr, diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h index d6fe003..1314956 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h @@ -13,15 +13,15 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/FileSystemOptions.h" -#include "clang/Frontend/AnalyzerOptions.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/Frontend/MigratorOptions.h" #include "clang/Frontend/CodeGenOptions.h" #include "clang/Frontend/DependencyOutputOptions.h" -#include "clang/Frontend/DiagnosticOptions.h" #include "clang/Frontend/FrontendOptions.h" -#include "clang/Frontend/HeaderSearchOptions.h" #include "clang/Frontend/LangStandard.h" -#include "clang/Frontend/PreprocessorOptions.h" #include "clang/Frontend/PreprocessorOutputOptions.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" @@ -52,6 +52,19 @@ class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> { protected: /// Options controlling the language variant. IntrusiveRefCntPtr<LangOptions> LangOpts; + + /// Options controlling the target. + IntrusiveRefCntPtr<TargetOptions> TargetOpts; + + /// Options controlling the diagnostic engine. + IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts; + + /// Options controlling the \#include directive. + IntrusiveRefCntPtr<HeaderSearchOptions> HeaderSearchOpts; + + /// Options controlling the preprocessor (aside from \#include handling). + IntrusiveRefCntPtr<PreprocessorOptions> PreprocessorOpts; + public: CompilerInvocationBase(); @@ -59,6 +72,23 @@ public: LangOptions *getLangOpts() { return LangOpts.getPtr(); } const LangOptions *getLangOpts() const { return LangOpts.getPtr(); } + + TargetOptions &getTargetOpts() { return *TargetOpts.getPtr(); } + const TargetOptions &getTargetOpts() const { + return *TargetOpts.getPtr(); + } + + DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; } + + HeaderSearchOptions &getHeaderSearchOpts() { return *HeaderSearchOpts; } + const HeaderSearchOptions &getHeaderSearchOpts() const { + return *HeaderSearchOpts; + } + + PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; } + const PreprocessorOptions &getPreprocessorOpts() const { + return *PreprocessorOpts; + } }; /// \brief Helper class for holding the data necessary to invoke the compiler. @@ -68,7 +98,7 @@ public: /// options, the warning flags, and so on. class CompilerInvocation : public CompilerInvocationBase { /// Options controlling the static analyzer. - AnalyzerOptions AnalyzerOpts; + AnalyzerOptionsRef AnalyzerOpts; MigratorOptions MigratorOpts; @@ -78,29 +108,17 @@ class CompilerInvocation : public CompilerInvocationBase { /// Options controlling dependency output. DependencyOutputOptions DependencyOutputOpts; - /// Options controlling the diagnostic engine. - DiagnosticOptions DiagnosticOpts; - /// Options controlling file system operations. FileSystemOptions FileSystemOpts; /// Options controlling the frontend itself. FrontendOptions FrontendOpts; - /// Options controlling the \#include directive. - HeaderSearchOptions HeaderSearchOpts; - - /// Options controlling the preprocessor (aside from \#include handling). - PreprocessorOptions PreprocessorOpts; - /// Options controlling preprocessed output. PreprocessorOutputOptions PreprocessorOutputOpts; - /// Options controlling the target. - TargetOptions TargetOpts; - public: - CompilerInvocation() {} + CompilerInvocation() : AnalyzerOpts(new AnalyzerOptions()) {} /// @name Utility Methods /// @{ @@ -127,10 +145,6 @@ public: /// executable), for finding the builtin compiler path. static std::string GetResourcesPath(const char *Argv0, void *MainAddr); - /// \brief Convert the CompilerInvocation to a list of strings suitable for - /// passing to CreateFromArgs. - void toArgs(std::vector<std::string> &Res) const; - /// \brief Set language defaults for the given input language and /// language standard in the given LangOptions object. /// @@ -148,8 +162,7 @@ public: /// @name Option Subgroups /// @{ - AnalyzerOptions &getAnalyzerOpts() { return AnalyzerOpts; } - const AnalyzerOptions &getAnalyzerOpts() const { + AnalyzerOptionsRef getAnalyzerOpts() const { return AnalyzerOpts; } @@ -170,29 +183,16 @@ public: return DependencyOutputOpts; } - DiagnosticOptions &getDiagnosticOpts() { return DiagnosticOpts; } - const DiagnosticOptions &getDiagnosticOpts() const { return DiagnosticOpts; } - FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; } const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } - HeaderSearchOptions &getHeaderSearchOpts() { return HeaderSearchOpts; } - const HeaderSearchOptions &getHeaderSearchOpts() const { - return HeaderSearchOpts; - } - FrontendOptions &getFrontendOpts() { return FrontendOpts; } const FrontendOptions &getFrontendOpts() const { return FrontendOpts; } - PreprocessorOptions &getPreprocessorOpts() { return PreprocessorOpts; } - const PreprocessorOptions &getPreprocessorOpts() const { - return PreprocessorOpts; - } - PreprocessorOutputOptions &getPreprocessorOutputOpts() { return PreprocessorOutputOpts; } @@ -200,11 +200,6 @@ public: return PreprocessorOutputOpts; } - TargetOptions &getTargetOpts() { return TargetOpts; } - const TargetOptions &getTargetOpts() const { - return TargetOpts; - } - /// @} }; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h deleted file mode 100644 index 8dec37c..0000000 --- a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticOptions.h +++ /dev/null @@ -1,111 +0,0 @@ -//===--- DiagnosticOptions.h ------------------------------------*- 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_FRONTEND_DIAGNOSTICOPTIONS_H -#define LLVM_CLANG_FRONTEND_DIAGNOSTICOPTIONS_H - -#include "clang/Basic/Diagnostic.h" - -#include <string> -#include <vector> - -namespace clang { - -/// DiagnosticOptions - Options for controlling the compiler diagnostics -/// engine. -class DiagnosticOptions { -public: - unsigned IgnoreWarnings : 1; /// -w - unsigned NoRewriteMacros : 1; /// -Wno-rewrite-macros - unsigned Pedantic : 1; /// -pedantic - unsigned PedanticErrors : 1; /// -pedantic-errors - unsigned ShowColumn : 1; /// Show column number on diagnostics. - unsigned ShowLocation : 1; /// Show source location information. - unsigned ShowCarets : 1; /// Show carets in diagnostics. - unsigned ShowFixits : 1; /// Show fixit information. - unsigned ShowSourceRanges : 1; /// Show source ranges in numeric form. - unsigned ShowParseableFixits : 1; /// Show machine parseable fix-its. - unsigned ShowOptionNames : 1; /// Show the option name for mappable - /// diagnostics. - unsigned ShowNoteIncludeStack : 1; /// Show include stacks for notes. - unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number, - /// 2 -> Full Name. - - unsigned Format : 2; /// Format for diagnostics: - enum TextDiagnosticFormat { Clang, Msvc, Vi }; - - unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences. - unsigned ShowOverloads : 1; /// Overload candidates to show. Values from - /// DiagnosticsEngine::OverloadsShown - unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected - /// diagnostics, indicated by markers in the - /// input source file. - - unsigned ElideType: 1; /// Elide identical types in template diffing - unsigned ShowTemplateTree: 1; /// Print a template tree when diffing - - unsigned ErrorLimit; /// Limit # errors emitted. - unsigned MacroBacktraceLimit; /// Limit depth of macro expansion backtrace. - unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace. - unsigned ConstexprBacktraceLimit; /// Limit depth of constexpr backtrace. - - /// The distance between tab stops. - unsigned TabStop; - enum { DefaultTabStop = 8, MaxTabStop = 100, - DefaultMacroBacktraceLimit = 6, - DefaultTemplateBacktraceLimit = 10, - DefaultConstexprBacktraceLimit = 10 }; - - /// Column limit for formatting message diagnostics, or 0 if unused. - unsigned MessageLength; - - /// If non-empty, a file to log extended build information to, for development - /// testing and analysis. - std::string DumpBuildInformation; - - /// The file to log diagnostic output to. - std::string DiagnosticLogFile; - - /// The file to serialize diagnostics to (non-appending). - std::string DiagnosticSerializationFile; - - /// The list of -W... options used to alter the diagnostic mappings, with the - /// prefixes removed. - std::vector<std::string> Warnings; - -public: - DiagnosticOptions() { - IgnoreWarnings = 0; - TabStop = DefaultTabStop; - MessageLength = 0; - NoRewriteMacros = 0; - Pedantic = 0; - PedanticErrors = 0; - ShowCarets = 1; - ShowColors = 0; - ShowOverloads = DiagnosticsEngine::Ovl_All; - ShowColumn = 1; - ShowFixits = 1; - ShowLocation = 1; - ShowOptionNames = 0; - ShowCategories = 0; - Format = Clang; - ShowSourceRanges = 0; - ShowParseableFixits = 0; - VerifyDiagnostics = 0; - ErrorLimit = 0; - TemplateBacktraceLimit = DefaultTemplateBacktraceLimit; - MacroBacktraceLimit = DefaultMacroBacktraceLimit; - ConstexprBacktraceLimit = DefaultConstexprBacktraceLimit; - } -}; - -} // end namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h index 09d7ecb..086bb13 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h @@ -44,7 +44,7 @@ typedef llvm::PointerUnion<const Diagnostic *, class DiagnosticRenderer { protected: const LangOptions &LangOpts; - const DiagnosticOptions &DiagOpts; + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; /// \brief The location of the previous diagnostic if known. /// @@ -66,7 +66,7 @@ protected: DiagnosticsEngine::Level LastLevel; DiagnosticRenderer(const LangOptions &LangOpts, - const DiagnosticOptions &DiagOpts); + DiagnosticOptions *DiagOpts); virtual ~DiagnosticRenderer(); @@ -124,7 +124,7 @@ public: /// \param Ranges The underlined ranges for this code snippet. /// \param FixItHints The FixIt hints active for this diagnostic. /// \param SM The SourceManager; will be null if the diagnostic came from the - /// frontend, thus \param Loc will be invalid. + /// frontend, thus \p Loc will be invalid. void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> FixItHints, @@ -139,7 +139,7 @@ public: class DiagnosticNoteRenderer : public DiagnosticRenderer { public: DiagnosticNoteRenderer(const LangOptions &LangOpts, - const DiagnosticOptions &DiagOpts) + DiagnosticOptions *DiagOpts) : DiagnosticRenderer(LangOpts, DiagOpts) {} virtual ~DiagnosticNoteRenderer(); diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h index c0056de..3283444 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h @@ -109,7 +109,7 @@ public: /// @{ bool isCurrentFileAST() const { - assert(!CurrentInput.File.empty() && "No current file!"); + assert(!CurrentInput.isEmpty() && "No current file!"); return CurrentASTUnit != 0; } @@ -117,14 +117,14 @@ public: return CurrentInput; } - const std::string &getCurrentFile() const { - assert(!CurrentInput.File.empty() && "No current file!"); - return CurrentInput.File; + const StringRef getCurrentFile() const { + assert(!CurrentInput.isEmpty() && "No current file!"); + return CurrentInput.getFile(); } InputKind getCurrentFileKind() const { - assert(!CurrentInput.File.empty() && "No current file!"); - return CurrentInput.Kind; + assert(!CurrentInput.isEmpty() && "No current file!"); + return CurrentInput.getKind(); } ASTUnit &getCurrentASTUnit() const { @@ -167,8 +167,8 @@ public: /// @name Public Action Interface /// @{ - /// BeginSourceFile - Prepare the action for processing the input file \arg - /// Filename; this is run after the options and frontend have been + /// BeginSourceFile - Prepare the action for processing the input file + /// \p Input; this is run after the options and frontend have been /// initialized, but prior to executing any per-file processing. /// /// \param CI - The compiler instance this action is being run from. The diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h index ce1cd9b..db2f5a5 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h @@ -16,6 +16,10 @@ #include <string> #include <vector> +namespace llvm { +class MemoryBuffer; +} + namespace clang { namespace frontend { @@ -72,19 +76,41 @@ enum InputKind { /// \brief An input file for the front end. -struct FrontendInputFile { +class FrontendInputFile { /// \brief The file name, or "-" to read from standard input. std::string File; + llvm::MemoryBuffer *Buffer; + /// \brief The kind of input, e.g., C source, AST file, LLVM IR. InputKind Kind; /// \brief Whether we're dealing with a 'system' input (vs. a 'user' input). bool IsSystem; - - FrontendInputFile() : Kind(IK_None) { } + +public: + FrontendInputFile() : Buffer(0), Kind(IK_None) { } FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false) - : File(File.str()), Kind(Kind), IsSystem(IsSystem) { } + : File(File.str()), Buffer(0), Kind(Kind), IsSystem(IsSystem) { } + FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind, + bool IsSystem = false) + : Buffer(buffer), Kind(Kind), IsSystem(IsSystem) { } + + InputKind getKind() const { return Kind; } + bool isSystem() const { return IsSystem; } + + bool isEmpty() const { return File.empty() && Buffer == 0; } + bool isFile() const { return !isBuffer(); } + bool isBuffer() const { return Buffer != 0; } + + StringRef getFile() const { + assert(isFile()); + return File; + } + llvm::MemoryBuffer *getBuffer() const { + assert(isBuffer()); + return Buffer; + } }; /// FrontendOptions - Options for controlling the behavior of the frontend. diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h index e6f4403..f07cb02 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h @@ -18,16 +18,17 @@ namespace clang { namespace frontend { enum LangFeatures { - BCPLComment = (1 << 0), + LineComment = (1 << 0), C89 = (1 << 1), C99 = (1 << 2), C11 = (1 << 3), CPlusPlus = (1 << 4), CPlusPlus0x = (1 << 5), - Digraphs = (1 << 6), - GNUMode = (1 << 7), - HexFloat = (1 << 8), - ImplicitInt = (1 << 9) + CPlusPlus1y = (1 << 6), + Digraphs = (1 << 7), + GNUMode = (1 << 8), + HexFloat = (1 << 9), + ImplicitInt = (1 << 10) }; } @@ -53,8 +54,8 @@ public: /// getDescription - Get the description of this standard. const char *getDescription() const { return Description; } - /// hasBCPLComments - Language supports '//' comments. - bool hasBCPLComments() const { return Flags & frontend::BCPLComment; } + /// Language supports '//' comments. + bool hasLineComments() const { return Flags & frontend::LineComment; } /// isC89 - Language is a superset of C89. bool isC89() const { return Flags & frontend::C89; } @@ -71,6 +72,9 @@ public: /// isCPlusPlus0x - Language is a C++0x variant. bool isCPlusPlus0x() const { return Flags & frontend::CPlusPlus0x; } + /// isCPlusPlus1y - Language is a C++1y variant. + bool isCPlusPlus1y() const { return Flags & frontend::CPlusPlus1y; } + /// hasDigraphs - Language supports digraphs. bool hasDigraphs() const { return Flags & frontend::Digraphs; } diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def index a604d4b..10807b7 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def @@ -36,91 +36,99 @@ LANGSTANDARD(c94, "iso9899:199409", LANGSTANDARD(gnu89, "gnu89", "ISO C 1990 with GNU extensions", - BCPLComment | C89 | Digraphs | GNUMode | ImplicitInt) + LineComment | C89 | Digraphs | GNUMode | ImplicitInt) LANGSTANDARD(gnu90, "gnu90", "ISO C 1990 with GNU extensions", - BCPLComment | C89 | Digraphs | GNUMode | ImplicitInt) + LineComment | C89 | Digraphs | GNUMode | ImplicitInt) // C99-ish modes LANGSTANDARD(c99, "c99", "ISO C 1999", - BCPLComment | C99 | Digraphs | HexFloat) + LineComment | C99 | Digraphs | HexFloat) LANGSTANDARD(c9x, "c9x", "ISO C 1999", - BCPLComment | C99 | Digraphs | HexFloat) + LineComment | C99 | Digraphs | HexFloat) LANGSTANDARD(iso9899_1999, "iso9899:1999", "ISO C 1999", - BCPLComment | C99 | Digraphs | HexFloat) + LineComment | C99 | Digraphs | HexFloat) LANGSTANDARD(iso9899_199x, "iso9899:199x", "ISO C 1999", - BCPLComment | C99 | Digraphs | HexFloat) + LineComment | C99 | Digraphs | HexFloat) LANGSTANDARD(gnu99, "gnu99", "ISO C 1999 with GNU extensions", - BCPLComment | C99 | Digraphs | GNUMode | HexFloat) + LineComment | C99 | Digraphs | GNUMode | HexFloat) LANGSTANDARD(gnu9x, "gnu9x", "ISO C 1999 with GNU extensions", - BCPLComment | C99 | Digraphs | GNUMode | HexFloat) + LineComment | C99 | Digraphs | GNUMode | HexFloat) // C11 modes LANGSTANDARD(c11, "c11", "ISO C 2011", - BCPLComment | C99 | C11 | Digraphs | HexFloat) + LineComment | C99 | C11 | Digraphs | HexFloat) LANGSTANDARD(c1x, "c1x", "ISO C 2011", - BCPLComment | C99 | C11 | Digraphs | HexFloat) + LineComment | C99 | C11 | Digraphs | HexFloat) LANGSTANDARD(iso9899_2011, "iso9899:2011", "ISO C 2011", - BCPLComment | C99 | C11 | Digraphs | HexFloat) + LineComment | C99 | C11 | Digraphs | HexFloat) LANGSTANDARD(iso9899_201x, "iso9899:2011", "ISO C 2011", - BCPLComment | C99 | C11 | Digraphs | HexFloat) + LineComment | C99 | C11 | Digraphs | HexFloat) LANGSTANDARD(gnu11, "gnu11", "ISO C 2011 with GNU extensions", - BCPLComment | C99 | C11 | Digraphs | GNUMode | HexFloat) + LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat) LANGSTANDARD(gnu1x, "gnu1x", "ISO C 2011 with GNU extensions", - BCPLComment | C99 | C11 | Digraphs | GNUMode | HexFloat) + LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat) // C++ modes LANGSTANDARD(cxx98, "c++98", "ISO C++ 1998 with amendments", - BCPLComment | CPlusPlus | Digraphs) + LineComment | CPlusPlus | Digraphs) LANGSTANDARD(cxx03, "c++03", "ISO C++ 1998 with amendments", - BCPLComment | CPlusPlus | Digraphs) + LineComment | CPlusPlus | Digraphs) LANGSTANDARD(gnucxx98, "gnu++98", "ISO C++ 1998 with amendments and GNU extensions", - BCPLComment | CPlusPlus | Digraphs | GNUMode) + LineComment | CPlusPlus | Digraphs | GNUMode) LANGSTANDARD(cxx0x, "c++0x", "ISO C++ 2011 with amendments", - BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs) + LineComment | CPlusPlus | CPlusPlus0x | Digraphs) LANGSTANDARD(cxx11, "c++11", "ISO C++ 2011 with amendments", - BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs) + LineComment | CPlusPlus | CPlusPlus0x | Digraphs) LANGSTANDARD(gnucxx0x, "gnu++0x", "ISO C++ 2011 with amendments and GNU extensions", - BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode) + LineComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode) LANGSTANDARD(gnucxx11, "gnu++11", "ISO C++ 2011 with amendments and GNU extensions", - BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode) + LineComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode) + +LANGSTANDARD(cxx1y, "c++1y", + "Working draft for ISO C++ 2014", + LineComment | CPlusPlus | CPlusPlus0x | CPlusPlus1y | Digraphs) +LANGSTANDARD(gnucxx1y, "gnu++1y", + "Working draft for ISO C++ 2014 with GNU extensions", + LineComment | CPlusPlus | CPlusPlus0x | CPlusPlus1y | Digraphs | + GNUMode) // OpenCL LANGSTANDARD(opencl, "cl", "OpenCL 1.0", - BCPLComment | C99 | Digraphs | HexFloat) + LineComment | C99 | Digraphs | HexFloat) LANGSTANDARD(opencl11, "CL1.1", "OpenCL 1.1", - BCPLComment | C99 | Digraphs | HexFloat) + LineComment | C99 | Digraphs | HexFloat) LANGSTANDARD(opencl12, "CL1.2", "OpenCL 1.2", - BCPLComment | C99 | Digraphs | HexFloat) + LineComment | C99 | Digraphs | HexFloat) // CUDA LANGSTANDARD(cuda, "cuda", "NVIDIA CUDA(tm)", - BCPLComment | CPlusPlus | Digraphs) + LineComment | CPlusPlus | Digraphs) #undef LANGSTANDARD diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h b/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h index 4de15f2..f4fa876 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h @@ -42,7 +42,7 @@ class LogDiagnosticPrinter : public DiagnosticConsumer { raw_ostream &OS; const LangOptions *LangOpts; - const DiagnosticOptions *DiagOpts; + llvm::IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; SourceLocation LastWarningLoc; FullSourceLoc LastLoc; @@ -54,7 +54,7 @@ class LogDiagnosticPrinter : public DiagnosticConsumer { std::string DwarfDebugFlags; public: - LogDiagnosticPrinter(raw_ostream &OS, const DiagnosticOptions &Diags, + LogDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions *Diags, bool OwnsOutputStream = false); virtual ~LogDiagnosticPrinter(); diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/MultiplexConsumer.h b/contrib/llvm/tools/clang/include/clang/Frontend/MultiplexConsumer.h index ffa7b4a..539f2c5 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/MultiplexConsumer.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/MultiplexConsumer.h @@ -52,7 +52,6 @@ public: virtual void InitializeSema(Sema &S); virtual void ForgetSema(); - static bool classof(const MultiplexConsumer *) { return true; } private: std::vector<ASTConsumer*> Consumers; // Owns these. OwningPtr<MultiplexASTMutationListener> MutationListener; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h index aa0695f..ab70afd 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h @@ -54,7 +54,7 @@ enum RecordIDs { /// (via libclang) without needing to parse Clang's command line output. /// DiagnosticConsumer *create(llvm::raw_ostream *OS, - const DiagnosticOptions &diags); + DiagnosticOptions *diags); } // end serialized_diags namespace } // end clang namespace diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h index c869c08..51f841d 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h @@ -40,7 +40,7 @@ class TextDiagnostic : public DiagnosticRenderer { public: TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts, - const DiagnosticOptions &DiagOpts); + DiagnosticOptions *DiagOpts); virtual ~TextDiagnostic(); diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h index 23cf521..91ac3c8 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h @@ -18,6 +18,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" namespace clang { class DiagnosticOptions; @@ -26,7 +27,7 @@ class TextDiagnostic; class TextDiagnosticPrinter : public DiagnosticConsumer { raw_ostream &OS; - const DiagnosticOptions *DiagOpts; + llvm::IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; /// \brief Handle to the currently active text diagnostic emitter. OwningPtr<TextDiagnostic> TextDiag; @@ -37,7 +38,7 @@ class TextDiagnosticPrinter : public DiagnosticConsumer { unsigned OwnsOutputStream : 1; public: - TextDiagnosticPrinter(raw_ostream &os, const DiagnosticOptions &diags, + TextDiagnosticPrinter(raw_ostream &os, DiagnosticOptions *diags, bool OwnsOutputStream = false); virtual ~TextDiagnosticPrinter(); diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h b/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h index a74589e..06a3b24 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h @@ -12,9 +12,9 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Lex/Preprocessor.h" -#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/STLExtras.h" #include <climits> @@ -33,7 +33,9 @@ class FileEntry; /// Indicating that a line expects an error or a warning is simple. Put a /// comment on the line that has the diagnostic, use: /// -/// expected-{error,warning,note} +/// \code +/// expected-{error,warning,note} +/// \endcode /// /// to tag if it's an expected error or warning, and place the expected text /// between {{ and }} markers. The full text doesn't have to be included, only @@ -94,12 +96,15 @@ class FileEntry; /// /// In this example, the diagnostic may appear only once, if at all. /// -/// Regex matching mode may be selected by appending '-re' to type. Example: +/// Regex matching mode may be selected by appending '-re' to type, such as: /// +/// \code /// expected-error-re +/// \endcode /// /// Examples matching error: "variable has incomplete type 'struct s'" /// +/// \code /// // expected-error {{variable has incomplete type 'struct s'}} /// // expected-error {{variable has incomplete type}} /// @@ -107,6 +112,15 @@ class FileEntry; /// // expected-error-re {{variable has has type 'struct .*'}} /// // expected-error-re {{variable has has type 'struct (.*)'}} /// // expected-error-re {{variable has has type 'struct[[:space:]](.*)'}} +/// \endcode +/// +/// VerifyDiagnosticConsumer expects at least one expected-* directive to +/// be found inside the source code. If no diagnostics are expected the +/// following directive can be used to indicate this: +/// +/// \code +/// // expected-no-diagnostics +/// \endcode /// class VerifyDiagnosticConsumer: public DiagnosticConsumer, public CommentHandler { @@ -146,8 +160,8 @@ public: } private: - Directive(const Directive&); // DO NOT IMPLEMENT - void operator=(const Directive&); // DO NOT IMPLEMENT + Directive(const Directive &) LLVM_DELETED_FUNCTION; + void operator=(const Directive &) LLVM_DELETED_FUNCTION; }; typedef std::vector<Directive*> DirectiveList; @@ -166,10 +180,12 @@ public: } }; -#ifndef NDEBUG - typedef llvm::DenseSet<FileID> FilesWithDiagnosticsSet; - typedef llvm::SmallPtrSet<const FileEntry *, 4> FilesParsedForDirectivesSet; -#endif + enum DirectiveStatus { + HasNoDirectives, + HasNoDirectivesReported, + HasExpectedNoDiagnostics, + HasOtherExpectedDirectives + }; private: DiagnosticsEngine &Diags; @@ -177,13 +193,36 @@ private: bool OwnsPrimaryClient; OwningPtr<TextDiagnosticBuffer> Buffer; const Preprocessor *CurrentPreprocessor; + const LangOptions *LangOpts; + SourceManager *SrcManager; unsigned ActiveSourceFiles; -#ifndef NDEBUG - FilesWithDiagnosticsSet FilesWithDiagnostics; - FilesParsedForDirectivesSet FilesParsedForDirectives; -#endif + DirectiveStatus Status; ExpectedData ED; + void CheckDiagnostics(); + void setSourceManager(SourceManager &SM) { + assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!"); + SrcManager = &SM; + } + +#ifndef NDEBUG + class UnparsedFileStatus { + llvm::PointerIntPair<const FileEntry *, 1, bool> Data; + + public: + UnparsedFileStatus(const FileEntry *File, bool FoundDirectives) + : Data(File, FoundDirectives) {} + + const FileEntry *getFile() const { return Data.getPointer(); } + bool foundDirectives() const { return Data.getInt(); } + }; + + typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap; + typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap; + + ParsedFilesMap ParsedFiles; + UnparsedFilesMap UnparsedFiles; +#endif public: /// Create a new verifying diagnostic client, which will issue errors to @@ -197,12 +236,19 @@ public: virtual void EndSourceFile(); - /// \brief Manually register a file as parsed. - inline void appendParsedFile(const FileEntry *File) { -#ifndef NDEBUG - FilesParsedForDirectives.insert(File); -#endif - } + enum ParsedStatus { + /// File has been processed via HandleComment. + IsParsed, + + /// File has diagnostics and may have directives. + IsUnparsed, + + /// File has diagnostics but guaranteed no directives. + IsUnparsedNoDirectives + }; + + /// \brief Update lists of parsed and unparsed files. + void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS); virtual bool HandleComment(Preprocessor &PP, SourceRange Comment); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/ExternalPreprocessorSource.h b/contrib/llvm/tools/clang/include/clang/Lex/ExternalPreprocessorSource.h index f172b5c..d2e2412 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/ExternalPreprocessorSource.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/ExternalPreprocessorSource.h @@ -28,9 +28,6 @@ public: /// \brief Read the set of macros defined by this external macro source. virtual void ReadDefinedMacros() = 0; - /// \brief Read the definition for the given macro. - virtual void LoadMacroDefinition(IdentifierInfo *II) = 0; - /// \brief Update an out-of-date identifier. virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0; }; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h index 107408d..8473a6a 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderMap.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_LEX_HEADERMAP_H #include "clang/Basic/LLVM.h" +#include "llvm/Support/Compiler.h" namespace llvm { class MemoryBuffer; @@ -30,8 +31,8 @@ namespace clang { /// symlinks to files. Its advantages are that it is dense and more efficient /// to create and process than a directory of symlinks. class HeaderMap { - HeaderMap(const HeaderMap&); // DO NOT IMPLEMENT - void operator=(const HeaderMap&); // DO NOT IMPLEMENT + HeaderMap(const HeaderMap &) LLVM_DELETED_FUNCTION; + void operator=(const HeaderMap &) LLVM_DELETED_FUNCTION; const llvm::MemoryBuffer *FileBuffer; bool NeedsBSwap; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h index 8e9491f..4334db7 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h @@ -17,6 +17,7 @@ #include "clang/Lex/DirectoryLookup.h" #include "clang/Lex/ModuleMap.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/Allocator.h" @@ -29,6 +30,7 @@ class DiagnosticsEngine; class ExternalIdentifierLookup; class FileEntry; class FileManager; +class HeaderSearchOptions; class IdentifierInfo; /// \brief The preprocessor keeps track of this information for each @@ -131,8 +133,10 @@ class HeaderSearch { bool IsUserSpecifiedSystemFramework; }; + /// \brief Header-search options used to initialize this header search. + llvm::IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts; + FileManager &FileMgr; - DiagnosticsEngine &Diags; /// \#include search path information. Requests for \#include "x" search the /// directory of the \#including file first, then each directory in SearchDirs /// consecutively. Requests for <x> search the current dir first, then each @@ -207,17 +211,21 @@ class HeaderSearch { unsigned NumFrameworkLookups, NumSubFrameworkLookups; // HeaderSearch doesn't support default or copy construction. - explicit HeaderSearch(); - explicit HeaderSearch(const HeaderSearch&); - void operator=(const HeaderSearch&); - + HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION; + void operator=(const HeaderSearch&) LLVM_DELETED_FUNCTION; + friend class DirectoryLookup; public: - HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags, + HeaderSearch(llvm::IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, + FileManager &FM, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target); ~HeaderSearch(); + /// \brief Retrieve the header-search options with which this header search + /// was initialized. + HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; } + FileManager &getFileMgr() const { return FileMgr; } /// \brief Interface for setting the file search paths. @@ -283,6 +291,11 @@ public: /// \brief Retrieve the path to the module cache. StringRef getModuleCachePath() const { return ModuleCachePath; } + + /// \brief Consider modules when including files from this directory. + void setDirectoryHasModuleMap(const DirectoryEntry* Dir) { + DirectoryHasModuleMap[Dir] = true; + } /// \brief Forget everything we know about headers so far. void ClearFileInfo() { diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h index ebc8f26..468fefa 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/HeaderSearchOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h @@ -7,9 +7,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H -#define LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H +#ifndef LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H +#define LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" #include <vector> @@ -36,7 +37,7 @@ namespace frontend { /// HeaderSearchOptions - Helper class for storing options related to the /// initialization of the HeaderSearch object. -class HeaderSearchOptions { +class HeaderSearchOptions : public llvm::RefCountedBase<HeaderSearchOptions> { public: struct Entry { std::string Path; @@ -125,7 +126,7 @@ public: UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false) {} - /// AddPath - Add the \arg Path path to the specified \arg Group list. + /// AddPath - Add the \p Path path to the specified \p Group list. void AddPath(StringRef Path, frontend::IncludeDirGroup Group, bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot, bool IsInternal = false, bool ImplicitExternC = false) { @@ -134,7 +135,7 @@ public: } /// AddSystemHeaderPrefix - Override whether \#include directives naming a - /// path starting with \arg Prefix should be considered as naming a system + /// path starting with \p Prefix should be considered as naming a system /// header. void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { SystemHeaderPrefixes.push_back(SystemHeaderPrefix(Prefix, IsSystemHeader)); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h b/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h index ca233de..407b644 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h @@ -31,11 +31,11 @@ class DiagnosticBuilder; 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. + /// 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. + /// A Perforce-style conflict marker, initiated by 4 ">"s, + /// separated by 4 "="s, and terminated by 4 "<"s. CMK_Perforce }; @@ -83,8 +83,8 @@ class Lexer : public PreprocessorLexer { // CurrentConflictMarkerState - The kind of conflict marker we are handling. ConflictMarkerKind CurrentConflictMarkerState; - Lexer(const Lexer&); // DO NOT IMPLEMENT - void operator=(const Lexer&); // DO NOT IMPLEMENT + Lexer(const Lexer &) LLVM_DELETED_FUNCTION; + void operator=(const Lexer &) LLVM_DELETED_FUNCTION; friend class Preprocessor; void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd); @@ -128,9 +128,7 @@ public: SourceLocation getFileLoc() const { return FileLoc; } /// Lex - Return the next token in the file. If this is the end of file, it - /// return the tok::eof token. Return true if an error occurred and - /// compilation should terminate, false if normal. This implicitly involves - /// the preprocessor. + /// return the tok::eof token. This implicitly involves the preprocessor. void Lex(Token &Result) { // Start a new token. Result.startToken(); @@ -278,8 +276,6 @@ public: /// \brief Given a location any where in a source buffer, find the location /// that corresponds to the beginning of the token in which the original /// source location lands. - /// - /// \param Loc static SourceLocation GetBeginningOfToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts); @@ -324,7 +320,7 @@ public: /// \brief Returns true if the given MacroID location points at the last /// token of the macro expansion. /// - /// \param MacroBegin If non-null and function returns true, it is set to + /// \param MacroEnd If non-null and function returns true, it is set to /// end location of the macro. static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, @@ -396,7 +392,36 @@ public: static std::pair<unsigned, bool> ComputePreamble(const llvm::MemoryBuffer *Buffer, const LangOptions &LangOpts, unsigned MaxLines = 0); - + + /// \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); + + /// \brief Returns true if the given character could appear in an identifier. + static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts); + + /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever + /// emit a warning. + static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size, + const LangOptions &LangOpts) { + // If this is not a trigraph and not a UCN or escaped newline, return + // quickly. + if (isObviouslySimpleCharacter(Ptr[0])) { + Size = 1; + return *Ptr; + } + + Size = 0; + return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts); + } + //===--------------------------------------------------------------------===// // Internal implementation interfaces. private: @@ -427,7 +452,6 @@ private: //===--------------------------------------------------------------------===// // Lexer character reading interfaces. -public: // This lexer is built on two interfaces for reading characters, both of which // automatically provide phase 1/2 translation. getAndAdvanceChar is used @@ -467,7 +491,6 @@ public: return C; } -private: /// ConsumeChar - When a character (identified by getCharAndSize) is consumed /// and added to a given token, check to see if there are diagnostics that /// need to be emitted or flags that need to be set on the token. If so, do @@ -503,22 +526,6 @@ private: /// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize /// method. char getCharAndSizeSlow(const char *Ptr, unsigned &Size, Token *Tok = 0); -public: - - /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever - /// emit a warning. - static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size, - const LangOptions &LangOpts) { - // If this is not a trigraph and not a UCN or escaped newline, return - // quickly. - if (isObviouslySimpleCharacter(Ptr[0])) { - Size = 1; - return *Ptr; - } - - Size = 0; - return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts); - } /// getEscapedNewLineSize - Return the size of the specified escaped newline, /// or 0 if it is not an escaped newline. P[-1] is known to be a "\" on entry @@ -530,22 +537,6 @@ public: /// 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); - - /// \brief Returns true if the given character could appear in an identifier. - static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts); - -private: - /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a /// diagnostic. static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size, @@ -571,15 +562,17 @@ private: bool LexEndOfFile (Token &Result, const char *CurPtr); bool SkipWhitespace (Token &Result, const char *CurPtr); - bool SkipBCPLComment (Token &Result, const char *CurPtr); + bool SkipLineComment (Token &Result, const char *CurPtr); bool SkipBlockComment (Token &Result, const char *CurPtr); - bool SaveBCPLComment (Token &Result, const char *CurPtr); + bool SaveLineComment (Token &Result, const char *CurPtr); bool IsStartOfConflictMarker(const char *CurPtr); bool HandleEndOfConflictMarker(const char *CurPtr); bool isCodeCompletionPoint(const char *CurPtr) const; void cutOffLexing() { BufferPtr = BufferEnd; } + + bool isHexaLiteral(const char *Start, const LangOptions &LangOpts); }; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h b/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h index bbce62d..3b68d1b 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h @@ -18,6 +18,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" #include "clang/Basic/TokenKinds.h" #include <cctype> @@ -48,8 +49,9 @@ class NumericLiteralParser { bool saw_exponent, saw_period, saw_ud_suffix; public: - NumericLiteralParser(const char *begin, const char *end, - SourceLocation Loc, Preprocessor &PP); + NumericLiteralParser(StringRef TokSpelling, + SourceLocation TokLoc, + Preprocessor &PP); bool hadError; bool isUnsigned; bool isLong; // This is *not* set for long long. @@ -230,8 +232,8 @@ public: private: void init(const Token *StringToks, unsigned NumStringToks); - bool CopyStringFragment(StringRef Fragment); - bool DiagnoseBadString(const Token& Tok); + bool CopyStringFragment(const Token &Tok, const char *TokBegin, + StringRef Fragment); void DiagnoseLexingError(SourceLocation Loc); }; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h index cbd201f..aba77d5 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h @@ -32,6 +32,12 @@ class MacroInfo { SourceLocation Location; /// EndLocation - The location of the last token in the macro. SourceLocation EndLocation; + /// \brief The location where the macro was #undef'd, or an invalid location + /// for macros that haven't been undefined. + SourceLocation UndefLocation; + /// \brief Previous definition, the identifier of this macro was defined to, + /// or NULL. + MacroInfo *PreviousDefinition; /// Arguments - The list of arguments for a function-like macro. This can be /// empty, for, e.g. "#define X()". In a C99-style variadic macro, this @@ -99,7 +105,16 @@ private: /// \brief Whether the macro has public (when described in a module). bool IsPublic : 1; - + + /// \brief Whether the macro definition is currently "hidden". + /// Note that this is transient state that is never serialized to the AST + /// file. + bool IsHidden : 1; + + /// \brief Whether the definition of this macro is ambiguous, due to + /// multiple definitions coming in from multiple modules. + bool IsAmbiguous : 1; + ~MacroInfo() { assert(ArgumentList == 0 && "Didn't call destroy before dtor!"); } @@ -128,10 +143,34 @@ public: /// setDefinitionEndLoc - Set the location of the last token in the macro. /// void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; } + /// getDefinitionEndLoc - Return the location of the last token in the macro. /// SourceLocation getDefinitionEndLoc() const { return EndLocation; } - + + /// \brief Set the location where macro was undefined. Can only be set once. + void setUndefLoc(SourceLocation UndefLoc) { + assert(UndefLocation.isInvalid() && "UndefLocation is already set!"); + assert(UndefLoc.isValid() && "Invalid UndefLoc!"); + UndefLocation = UndefLoc; + } + + /// \brief Get the location where macro was undefined. + SourceLocation getUndefLoc() const { return UndefLocation; } + + /// \brief Set previous definition of the macro with the same name. + void setPreviousDefinition(MacroInfo *PreviousDef) { + PreviousDefinition = PreviousDef; + } + + /// \brief Get previous definition of the macro with the same name. + MacroInfo *getPreviousDefinition() { return PreviousDefinition; } + + /// \brief Find macro definition active in the specified source location. If + /// this macro was not defined there, return NULL. + const MacroInfo *findDefinitionAtLoc(SourceLocation L, + SourceManager &SM) const; + /// \brief Get length in characters of the macro definition. unsigned getDefinitionLength(SourceManager &SM) const { if (IsDefinitionLengthCached) @@ -294,6 +333,23 @@ public: /// \brief Determine the location where this macro was explicitly made /// public or private within its module. SourceLocation getVisibilityLocation() { return VisibilityLocation; } + + /// \brief Determine whether this macro is currently defined (and has not + /// been #undef'd) or has been hidden. + bool isDefined() const { return UndefLocation.isInvalid() && !IsHidden; } + + /// \brief Determine whether this macro definition is hidden. + bool isHidden() const { return IsHidden; } + + /// \brief Set whether this macro definition is hidden. + void setHidden(bool Val) { IsHidden = Val; } + + /// \brief Determine whether this macro definition is ambiguous with + /// other macro definitions. + bool isAmbiguous() const { return IsAmbiguous; } + + /// \brief Set whether this macro definition is ambiguous. + void setAmbiguous(bool Val) { IsAmbiguous = Val; } private: unsigned getDefinitionLengthSlow(SourceManager &SM) const; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h b/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h index fe5abdf..082408d 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h @@ -52,10 +52,37 @@ class ModuleMap { /// \brief The top-level modules that are known. llvm::StringMap<Module *> Modules; - + + /// \brief A header that is known to reside within a given module, + /// whether it was included or excluded. + class KnownHeader { + llvm::PointerIntPair<Module *, 1, bool> Storage; + + public: + KnownHeader() : Storage(0, false) { } + KnownHeader(Module *M, bool Excluded) : Storage(M, Excluded) { } + + /// \brief Retrieve the module the header is stored in. + Module *getModule() const { return Storage.getPointer(); } + + /// \brief Whether this header is explicitly excluded from the module. + bool isExcluded() const { return Storage.getInt(); } + + /// \brief Whether this header is available in the module. + bool isAvailable() const { + return !isExcluded() && getModule()->isAvailable(); + } + + // \brief Whether this known header is valid (i.e., it has an + // associated module). + operator bool() const { return Storage.getPointer() != 0; } + }; + + typedef llvm::DenseMap<const FileEntry *, KnownHeader> HeadersMap; + /// \brief Mapping from each header to the module that owns the contents of the /// that header. - llvm::DenseMap<const FileEntry *, Module *> Headers; + HeadersMap Headers; /// \brief Mapping from directories with umbrella headers to the module /// that is generated from the umbrella header. @@ -64,7 +91,26 @@ class ModuleMap { /// in the module map over to the module that includes them via its umbrella /// header. llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs; - + + /// \brief A directory for which framework modules can be inferred. + struct InferredDirectory { + InferredDirectory() : InferModules(), InferSystemModules() { } + + /// \brief Whether to infer modules from this directory. + unsigned InferModules : 1; + + /// \brief Whether the modules we infer are [system] modules. + unsigned InferSystemModules : 1; + + /// \brief The names of modules that cannot be inferred within this + /// directory. + llvm::SmallVector<std::string, 2> ExcludedModules; + }; + + /// \brief A mapping from directories to information about inferring + /// framework modules from within those directories. + llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories; + friend class ModuleMapParser; /// \brief Resolve the given export declaration into an actual export @@ -170,7 +216,23 @@ public: std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit); - + + /// \brief Determine whether we can infer a framework module a framework + /// with the given name in the given + /// + /// \param ParentDir The directory that is the parent of the framework + /// directory. + /// + /// \param Name The name of the module. + /// + /// \param IsSystem Will be set to 'true' if the inferred module must be a + /// system module. + /// + /// \returns true if we are allowed to infer a framework module, and false + /// otherwise. + bool canInferFrameworkModule(const DirectoryEntry *ParentDir, + StringRef Name, bool &IsSystem); + /// \brief Infer the contents of a framework module map from the given /// framework directory. Module *inferFrameworkModule(StringRef ModuleName, @@ -215,7 +277,9 @@ public: void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir); /// \brief Adds this header to the given module. - void addHeader(Module *Mod, const FileEntry *Header); + /// \param Excluded Whether this header is explicitly excluded from the + /// module; otherwise, it's included in the module. + void addHeader(Module *Mod, const FileEntry *Header, bool Excluded); /// \brief Parse the given module map file, and record any modules we /// encounter. diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h index 962b4df..8ba02cc 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_LEX_PPCALLBACKS_H #include "clang/Lex/DirectoryLookup.h" +#include "clang/Lex/ModuleLoader.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/DiagnosticIDs.h" #include "llvm/ADT/StringRef.h" @@ -93,10 +94,10 @@ public: /// \param IsAngled Whether the file name was enclosed in angle brackets; /// otherwise, it was enclosed in quotes. /// - /// \param File The actual file that may be included by this inclusion - /// directive. + /// \param FilenameRange The character range of the quotes or angle brackets + /// for the written file name. /// - /// \param EndLoc The location of the last token within the inclusion + /// \param File The actual file that may be included by this inclusion /// directive. /// /// \param SearchPath Contains the search path which was used to find the file @@ -110,14 +111,34 @@ public: /// /// \param RelativePath The path relative to SearchPath, at which the include /// file was found. This is equal to FileName except for framework includes. + /// + /// \param Imported The module, whenever an inclusion directive was + /// automatically turned into a module import or null otherwise. + /// virtual void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, - SourceLocation EndLoc, StringRef SearchPath, - StringRef RelativePath) { + StringRef RelativePath, + const Module *Imported) { + } + + /// \brief Callback invoked whenever there was an explicit module-import + /// syntax. + /// + /// \param ImportLoc The location of import directive token. + /// + /// \param Path The identifiers (and their locations) of the module + /// "path", e.g., "std.vector" would be split into "std" and "vector". + /// + /// \param Imported The imported module; can be null if importing failed. + /// + virtual void moduleImport(SourceLocation ImportLoc, + ModuleIdPath Path, + const Module *Imported) { } /// \brief Callback invoked when the end of the main file is reached. @@ -266,14 +287,24 @@ public: const Token &IncludeTok, StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, - SourceLocation EndLoc, StringRef SearchPath, - StringRef RelativePath) { - First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, - EndLoc, SearchPath, RelativePath); - Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, - EndLoc, SearchPath, RelativePath); + StringRef RelativePath, + const Module *Imported) { + First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, + FilenameRange, File, SearchPath, RelativePath, + Imported); + Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, + FilenameRange, File, SearchPath, RelativePath, + Imported); + } + + virtual void moduleImport(SourceLocation ImportLoc, + ModuleIdPath Path, + const Module *Imported) { + First->moduleImport(ImportLoc, Path, Imported); + Second->moduleImport(ImportLoc, Path, Imported); } virtual void EndOfMainFile() { diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PPMutationListener.h b/contrib/llvm/tools/clang/include/clang/Lex/PPMutationListener.h new file mode 100644 index 0000000..5319c66 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Lex/PPMutationListener.h @@ -0,0 +1,43 @@ +//===--- PPMutationListener.h - Preprocessor Mutation 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 PPMutationListener interface. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_LEX_PPTMUTATIONLISTENER_H +#define LLVM_CLANG_LEX_PPTMUTATIONLISTENER_H + +#include "clang/Basic/SourceLocation.h" + +namespace clang { + +class MacroInfo; + +/// \brief A record that describes an update to a macro that was +/// originally loaded to an AST file and has been modified within the +/// current translation unit. +struct MacroUpdate { + /// \brief The source location at which this macro was #undef'd. + SourceLocation UndefLoc; +}; + +/// \brief An abstract interface that should be implemented by +/// listeners that want to be notified when a preprocessor entity gets +/// modified after its initial creation. +class PPMutationListener { +public: + virtual ~PPMutationListener(); + + /// \brief A macro has been #undef'd. + virtual void UndefinedMacro(MacroInfo *MI) { } +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h index f6a97a0..a9276e8 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h @@ -44,8 +44,8 @@ class PTHLexer : public PreprocessorLexer { /// to process when doing quick skipping of preprocessor blocks. const unsigned char* CurPPCondPtr; - PTHLexer(const PTHLexer&); // DO NOT IMPLEMENT - void operator=(const PTHLexer&); // DO NOT IMPLEMENT + PTHLexer(const PTHLexer &) LLVM_DELETED_FUNCTION; + void operator=(const PTHLexer &) LLVM_DELETED_FUNCTION; /// ReadToken - Used by PTHLexer to read tokens TokBuf. void ReadToken(Token& T); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h b/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h index 44f9ab3..e64dbd8 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PTHManager.h @@ -81,9 +81,8 @@ class PTHManager : public IdentifierInfoLookup { void* stringIdLookup, unsigned numIds, const unsigned char* spellingBase, const char *originalSourceFile); - // Do not implement. - PTHManager(); - void operator=(const PTHManager&); + PTHManager(const PTHManager &) LLVM_DELETED_FUNCTION; + void operator=(const PTHManager &) LLVM_DELETED_FUNCTION; /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached /// spelling for a token. diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h index fb3e081..57e51b7 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h @@ -94,9 +94,6 @@ namespace clang { /// entity. bool isInvalid() const { return Kind == InvalidKind; } - // Implement isa/cast/dyncast/etc. - static bool classof(const PreprocessedEntity *) { return true; } - // Only allow allocation of preprocessed entities using the allocator // in PreprocessingRecord or by doing a placement new. void* operator new(size_t bytes, PreprocessingRecord& PR, @@ -133,7 +130,6 @@ namespace clang { return PD->getKind() >= FirstPreprocessingDirective && PD->getKind() <= LastPreprocessingDirective; } - static bool classof(const PreprocessingDirective *) { return true; } }; /// \brief Record the location of a macro definition. @@ -155,7 +151,6 @@ namespace clang { static bool classof(const PreprocessedEntity *PE) { return PE->getKind() == MacroDefinitionKind; } - static bool classof(const MacroDefinition *) { return true; } }; /// \brief Records the location of a macro expansion. @@ -193,7 +188,6 @@ namespace clang { 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 @@ -227,13 +221,18 @@ namespace clang { /// This is a value of type InclusionKind. unsigned Kind : 2; + /// \brief Whether the inclusion directive was automatically turned into + /// a module import. + unsigned ImportedModule : 1; + /// \brief The file that was included. const FileEntry *File; public: InclusionDirective(PreprocessingRecord &PPRec, InclusionKind Kind, StringRef FileName, - bool InQuotes, const FileEntry *File, SourceRange Range); + bool InQuotes, bool ImportedModule, + const FileEntry *File, SourceRange Range); /// \brief Determine what kind of inclusion directive this is. InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); } @@ -244,6 +243,10 @@ namespace clang { /// \brief Determine whether the included file name was written in quotes; /// otherwise, it was written in angle brackets. bool wasInQuotes() const { return InQuotes; } + + /// \brief Determine whether the inclusion directive was automatically + /// turned into a module import. + bool importedModule() const { return ImportedModule; } /// \brief Retrieve the file entry for the actual file that was included /// by this directive. @@ -253,7 +256,6 @@ namespace clang { static bool classof(const PreprocessedEntity *PE) { return PE->getKind() == InclusionDirectiveKind; } - static bool classof(const InclusionDirective *) { return true; } }; /// \brief An abstract class that should be subclassed by any external source @@ -269,12 +271,12 @@ namespace clang { virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0; /// \brief Returns a pair of [Begin, End) indices of preallocated - /// preprocessed entities that \arg Range encompasses. + /// preprocessed entities that \p Range encompasses. virtual std::pair<unsigned, unsigned> findPreprocessedEntitiesInRange(SourceRange Range) = 0; /// \brief Optionally returns true or false if the preallocated preprocessed - /// entity with index \arg Index came from file \arg FID. + /// entity with index \p Index came from file \p FID. virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index, FileID FID) { return llvm::Optional<bool>(); @@ -343,14 +345,21 @@ namespace clang { /// 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; + /// Value -1 corresponds to element 0 in the loaded entities vector, + /// value -2 corresponds to element 1 in the loaded entities vector, etc. + /// Value 0 is an invalid value, the index to local entities is 1-based, + /// value 1 corresponds to element 0 in the local entities vector, + /// value 2 corresponds to element 1 in the local entities vector, etc. + class PPEntityID { + int ID; + explicit PPEntityID(int ID) : ID(ID) {} + friend class PreprocessingRecord; + public: + PPEntityID() : ID(0) {} + }; + + static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) { + return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1); } /// \brief Mapping from MacroInfo structures to their definitions. @@ -372,7 +381,7 @@ namespace clang { } /// \brief Returns a pair of [Begin, End) indices of local preprocessed - /// entities that \arg Range encompasses. + /// entities that \p Range encompasses. std::pair<unsigned, unsigned> findLocalPreprocessedEntitiesInRange(SourceRange Range) const; unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const; @@ -419,7 +428,7 @@ namespace clang { /// 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; + int Position; public: typedef PreprocessedEntity *value_type; @@ -430,11 +439,15 @@ namespace clang { iterator() : Self(0), Position(0) { } - iterator(PreprocessingRecord *Self, PPEntityID Position) + iterator(PreprocessingRecord *Self, int Position) : Self(Self), Position(Position) { } value_type operator*() const { - return Self->getPreprocessedEntity(Position); + bool isLoaded = Position < 0; + unsigned Index = isLoaded ? + Self->LoadedPreprocessedEntities.size() + Position : Position; + PPEntityID ID = Self->getPPEntityID(Index, isLoaded); + return Self->getPreprocessedEntity(ID); } value_type operator[](difference_type D) { @@ -539,15 +552,26 @@ namespace clang { return iterator(this, PreprocessedEntities.size()); } + /// \brief begin/end iterator pair for the given range of loaded + /// preprocessed entities. + std::pair<iterator, iterator> + getIteratorsForLoadedRange(unsigned start, unsigned count) { + unsigned end = start + count; + assert(end <= LoadedPreprocessedEntities.size()); + return std::make_pair( + iterator(this, int(start)-LoadedPreprocessedEntities.size()), + iterator(this, int(end)-LoadedPreprocessedEntities.size())); + } + /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities - /// that source range \arg R encompasses. + /// that source range \p R encompasses. /// /// \param R the range to look for preprocessed entities. /// std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R); - /// \brief Returns true if the preprocessed entity that \arg PPEI iterator - /// points to is coming from the file \arg FID. + /// \brief Returns true if the preprocessed entity that \p PPEI iterator + /// points to is coming from the file \p FID. /// /// Can be used to avoid implicit deserializations of preallocated /// preprocessed entities if we only care about entities of a specific file @@ -597,10 +621,11 @@ namespace clang { const Token &IncludeTok, StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, - SourceLocation EndLoc, StringRef SearchPath, - StringRef RelativePath); + StringRef RelativePath, + const Module *Imported); virtual void If(SourceLocation Loc, SourceRange ConditionRange); virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, SourceLocation IfLoc); @@ -613,11 +638,10 @@ namespace clang { /// query. struct { SourceRange Range; - std::pair<PPEntityID, PPEntityID> Result; + std::pair<int, int> Result; } CachedRangeQuery; - std::pair<PPEntityID, PPEntityID> - getPreprocessedEntitiesInRangeSlow(SourceRange R); + std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R); friend class ASTReader; friend class ASTWriter; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h index 02e3f1e..e9095fb 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h @@ -18,6 +18,7 @@ #include "clang/Lex/Lexer.h" #include "clang/Lex/PTHLexer.h" #include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/PPMutationListener.h" #include "clang/Lex/TokenLexer.h" #include "clang/Lex/PTHManager.h" #include "clang/Basic/Builtins.h" @@ -54,6 +55,28 @@ class CodeCompletionHandler; class DirectoryLookup; class PreprocessingRecord; class ModuleLoader; +class PreprocessorOptions; + +/// \brief Stores token information for comparing actual tokens with +/// predefined values. Only handles simple tokens and identifiers. +class TokenValue { + tok::TokenKind Kind; + IdentifierInfo *II; + +public: + TokenValue(tok::TokenKind Kind) : Kind(Kind), II(0) { + assert(Kind != tok::raw_identifier && "Raw identifiers are not supported."); + assert(Kind != tok::identifier && + "Identifiers should be created by TokenValue(IdentifierInfo *)"); + assert(!tok::isLiteral(Kind) && "Literals are not supported."); + assert(!tok::isAnnotation(Kind) && "Annotations are not supported."); + } + TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {} + bool operator==(const Token &Tok) const { + return Tok.getKind() == Kind && + (!II || II == Tok.getIdentifierInfo()); + } +}; /// Preprocessor - This object engages in a tight little dance with the lexer to /// efficiently preprocess tokens. Lexers know only about tokens within a @@ -61,6 +84,7 @@ class ModuleLoader; /// like the \#include stack, token expansion, etc. /// class Preprocessor : public RefCountedBase<Preprocessor> { + llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts; DiagnosticsEngine *Diags; LangOptions &LangOpts; const TargetInfo *Target; @@ -98,6 +122,8 @@ class Preprocessor : public RefCountedBase<Preprocessor> { IdentifierInfo *Ident__has_include; // __has_include IdentifierInfo *Ident__has_include_next; // __has_include_next IdentifierInfo *Ident__has_warning; // __has_warning + IdentifierInfo *Ident__building_module; // __building_module + IdentifierInfo *Ident__MODULE__; // __MODULE__ SourceLocation DATELoc, TIMELoc; unsigned CounterValue; // Next __COUNTER__ value. @@ -265,6 +291,11 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// encountered (e.g. a file is \#included, etc). PPCallbacks *Callbacks; + /// \brief Listener whose actions are invoked when an entity in the + /// preprocessor (e.g., a macro) that was loaded from an AST file is + /// later mutated. + PPMutationListener *Listener; + struct MacroExpandsInfo { Token Tok; MacroInfo *MI; @@ -274,10 +305,12 @@ class Preprocessor : public RefCountedBase<Preprocessor> { }; SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks; - /// Macros - For each IdentifierInfo with 'HasMacro' set, we keep a mapping - /// to the actual definition of the macro. + /// Macros - For each IdentifierInfo that was associated with a macro, we + /// keep a mapping to the history of all macro definitions and #undefs in + /// the reverse order (the latest one is in the head of the list). llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros; - + friend class ASTReader; + /// \brief Macros that we want to warn because they are not used at the end /// of the translation unit; we store just their SourceLocations instead /// something like MacroInfo*. The benefit of this is that when we are @@ -362,10 +395,9 @@ private: // Cached tokens state. /// allocation. MacroInfoChain *MICache; - MacroInfo *getInfoForMacro(IdentifierInfo *II) const; - public: - Preprocessor(DiagnosticsEngine &diags, LangOptions &opts, + Preprocessor(llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, + DiagnosticsEngine &diags, LangOptions &opts, const TargetInfo *target, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, @@ -382,6 +414,10 @@ public: /// \param Target Information about the target. void Initialize(const TargetInfo &Target); + /// \brief Retrieve the preprocessor options used to initialize this + /// preprocessor. + PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; } + DiagnosticsEngine &getDiagnostics() const { return *Diags; } void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; } @@ -457,37 +493,70 @@ public: Callbacks = C; } + /// \brief Attach an preprocessor mutation listener to the preprocessor. + /// + /// The preprocessor mutation listener provides the ability to track + /// modifications to the preprocessor entities committed after they were + /// initially created. + void setPPMutationListener(PPMutationListener *Listener) { + this->Listener = Listener; + } + + /// \brief Retrieve a pointer to the preprocessor mutation listener + /// associated with this preprocessor, if any. + PPMutationListener *getPPMutationListener() const { return Listener; } + /// \brief Given an identifier, return the MacroInfo it is \#defined to /// or null if it isn't \#define'd. MacroInfo *getMacroInfo(IdentifierInfo *II) const { if (!II->hasMacroDefinition()) return 0; - return getInfoForMacro(II); + MacroInfo *MI = getMacroInfoHistory(II); + assert(MI->getUndefLoc().isInvalid() && "Macro is undefined!"); + return MI; } - /// \brief Specify a macro for this identifier. - void setMacroInfo(IdentifierInfo *II, MacroInfo *MI, - bool LoadedFromAST = false); + /// \brief Given an identifier, return the (probably #undef'd) MacroInfo + /// representing the most recent macro definition. One can iterate over all + /// previous macro definitions from it. This method should only be called for + /// identifiers that hadMacroDefinition(). + MacroInfo *getMacroInfoHistory(IdentifierInfo *II) const; - /// macro_iterator/macro_begin/macro_end - This allows you to walk the current - /// state of the macro table. This visits every currently-defined macro. + /// \brief Specify a macro for this identifier. + void setMacroInfo(IdentifierInfo *II, MacroInfo *MI); + /// \brief Add a MacroInfo that was loaded from an AST file. + void addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI, + MacroInfo *Hint = 0); + /// \brief Make the given MacroInfo, that was loaded from an AST file and + /// previously hidden, visible. + void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroInfo *MI); + /// \brief Undefine a macro for this identifier. + void clearMacroInfo(IdentifierInfo *II); + + /// macro_iterator/macro_begin/macro_end - This allows you to walk the macro + /// history table. Currently defined macros have + /// IdentifierInfo::hasMacroDefinition() set and an empty + /// MacroInfo::getUndefLoc() at the head of the list. typedef llvm::DenseMap<IdentifierInfo*, MacroInfo*>::const_iterator macro_iterator; macro_iterator macro_begin(bool IncludeExternalMacros = true) const; macro_iterator macro_end(bool IncludeExternalMacros = true) const; + /// \brief Return the name of the macro defined before \p Loc that has + /// spelling \p Tokens. If there are multiple macros with same spelling, + /// return the last one defined. + StringRef getLastMacroWithSpelling(SourceLocation Loc, + ArrayRef<TokenValue> Tokens) const; + const std::string &getPredefines() const { return Predefines; } /// setPredefines - Set the predefines for this Preprocessor. These /// predefines are automatically injected when parsing the main file. void setPredefines(const char *P) { Predefines = P; } void setPredefines(const std::string &P) { Predefines = P; } - /// getIdentifierInfo - Return information about the specified preprocessor - /// identifier token. The version of this method that takes two character - /// pointers is preferred unless the identifier is already available as a - /// string (this avoids allocation and copying of memory to construct an - /// std::string). + /// Return information about the specified preprocessor + /// identifier token. IdentifierInfo *getIdentifierInfo(StringRef Name) const { return &Identifiers.get(Name); } @@ -501,8 +570,8 @@ public: } /// 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 + /// the preprocessor. If \p Namespace is non-null, then it should + /// be the namespace that \p Handler was added to. It is an error /// to remove a handler that has not been registered. void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler); void RemovePragmaHandler(PragmaHandler *Handler) { @@ -564,7 +633,8 @@ public: /// /// ILEnd specifies the location of the ')' for a function-like macro or the /// identifier for an object-like macro. - void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroArgs *Args); + void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro, + MacroArgs *Args); /// EnterTokenStream - Add a "macro" context to the top of the include stack, /// which will cause the lexer to start returning the specified tokens. @@ -724,6 +794,14 @@ public: CachedTokens[CachedLexPos-1] = Tok; } + /// TypoCorrectToken - Update the current token to represent the provided + /// identifier, in order to cache an action performed by typo correction. + void TypoCorrectToken(const Token &Tok) { + assert(Tok.getIdentifierInfo() && "Expected identifier token"); + if (CachedLexPos != 0 && isBacktrackEnabled()) + CachedTokens[CachedLexPos-1] = Tok; + } + /// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/ /// CurTokenLexer pointers. void recomputeCurLexerKind(); @@ -892,7 +970,7 @@ 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, + void CreateString(StringRef Str, Token &Tok, SourceLocation ExpansionLocStart = SourceLocation(), SourceLocation ExpansionLocEnd = SourceLocation()); @@ -929,7 +1007,7 @@ public: /// \brief Returns true if the given MacroID location points at the last /// token of the macro expansion. /// - /// \param MacroBegin If non-null and function returns true, it is set to + /// \param MacroEnd If non-null and function returns true, it is set to /// end location of the macro. bool isAtEndOfMacroExpansion(SourceLocation loc, SourceLocation *MacroEnd = 0) const { @@ -1103,10 +1181,10 @@ public: /// from a macro as multiple tokens, which need to be glued together. This /// occurs for code like: /// \code - /// \#define FOO <a/b.h> + /// \#define FOO <x/y.h> /// \#include FOO /// \endcode - /// because in this case, "<a/b.h>" is returned as 7 tokens, not one. + /// because in this case, "<x/y.h>" is returned as 7 tokens, not one. /// /// This code concatenates and consumes tokens up to the '>' token. It /// returns false if the > was found, otherwise it returns true if it finds @@ -1289,6 +1367,8 @@ private: // Macro handling. void HandleDefineDirective(Token &Tok); void HandleUndefDirective(Token &Tok); + void UndefineMacro(IdentifierInfo *II, MacroInfo *MI, + SourceLocation UndefLoc); // Conditional Inclusion. void HandleIfdefDirective(Token &Tok, bool isIfndef, diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h index 8a0b3cf..20fb8a0 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h @@ -69,8 +69,8 @@ protected: /// we are currently in. SmallVector<PPConditionalInfo, 4> ConditionalStack; - PreprocessorLexer(const PreprocessorLexer&); // DO NOT IMPLEMENT - void operator=(const PreprocessorLexer&); // DO NOT IMPLEMENT + PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION; + void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION; friend class Preprocessor; PreprocessorLexer(Preprocessor *pp, FileID fid); diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorOptions.h index d86a923..e5fe373 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorOptions.h @@ -7,9 +7,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_ -#define LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_ +#ifndef LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_ +#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_ +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include <cassert> @@ -38,7 +39,7 @@ enum ObjCXXARCStandardLibraryKind { /// PreprocessorOptions - This class is used for passing the various options /// used in preprocessor initialization to InitializePreprocessor(). -class PreprocessorOptions { +class PreprocessorOptions : public llvm::RefCountedBase<PreprocessorOptions> { public: std::vector<std::pair<std::string, bool/*isUndef*/> > Macros; std::vector<std::string> Includes; @@ -65,10 +66,6 @@ public: /// precompiled headers. bool DisablePCHValidation; - /// \brief When true, disables the use of the stat cache within a - /// precompiled header or AST file. - bool DisableStatCache; - /// \brief When true, a PCH with compiler errors will not be rejected. bool AllowPCHWithCompilerErrors; @@ -167,7 +164,7 @@ public: public: PreprocessorOptions() : UsePredefines(true), DetailedRecord(false), DetailedRecordConditionalDirectives(false), - DisablePCHValidation(false), DisableStatCache(false), + DisablePCHValidation(false), AllowPCHWithCompilerErrors(false), DumpDeserializedPCHDecls(false), PrecompiledPreambleBytes(0, true), diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Token.h b/contrib/llvm/tools/clang/include/clang/Lex/Token.h index 9c5a023..50b86c8 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Token.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Token.h @@ -90,26 +90,18 @@ public: /// \brief Return true if this is a raw identifier (when lexing /// in raw mode) or a non-keyword identifier (when lexing in non-raw mode). bool isAnyIdentifier() const { - return is(tok::identifier) || is(tok::raw_identifier); + return tok::isAnyIdentifier(getKind()); } - /// isLiteral - Return true if this is a "literal", like a numeric + /// \brief Return true if this is a "literal", like a numeric /// constant, string, etc. bool isLiteral() const { - return is(tok::numeric_constant) || is(tok::char_constant) || - 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); + return tok::isLiteral(getKind()); } + /// \brief Return true if this is any of tok::annot_* kind tokens. bool isAnnotation() const { -#define ANNOTATION(NAME) \ - if (is(tok::annot_##NAME)) \ - return true; -#include "clang/Basic/TokenKinds.def" - return false; + return tok::isAnnotation(getKind()); } /// \brief Return a source location identifier for the specified diff --git a/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h index 1330ad5..090402a 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h @@ -22,7 +22,7 @@ namespace clang { class Token; class MacroArgs; -/// TokenLexer - This implements a lexer that returns token from a macro body +/// TokenLexer - This implements a lexer that returns tokens from a macro body /// or token stream instead of lexing from a character buffer. This is used for /// macro expansion and _Pragma handling, for example. /// @@ -91,24 +91,25 @@ class TokenLexer { /// should not be subject to further macro expansion. bool DisableMacroExpansion : 1; - TokenLexer(const TokenLexer&); // DO NOT IMPLEMENT - void operator=(const TokenLexer&); // DO NOT IMPLEMENT + TokenLexer(const TokenLexer &) LLVM_DELETED_FUNCTION; + void operator=(const TokenLexer &) LLVM_DELETED_FUNCTION; public: /// Create a TokenLexer for the specified macro with the specified actual /// arguments. Note that this ctor takes ownership of the ActualArgs pointer. /// ILEnd specifies the location of the ')' for a function-like macro or the /// identifier for an object-like macro. - TokenLexer(Token &Tok, SourceLocation ILEnd, MacroArgs *ActualArgs, - Preprocessor &pp) + TokenLexer(Token &Tok, SourceLocation ILEnd, MacroInfo *MI, + MacroArgs *ActualArgs, Preprocessor &pp) : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) { - Init(Tok, ILEnd, ActualArgs); + Init(Tok, ILEnd, MI, ActualArgs); } /// Init - Initialize this TokenLexer to expand from the specified macro /// with the specified argument information. Note that this ctor takes /// ownership of the ActualArgs pointer. ILEnd specifies the location of the /// ')' for a function-like macro or the identifier for an object-like macro. - void Init(Token &Tok, SourceLocation ILEnd, MacroArgs *ActualArgs); + void Init(Token &Tok, SourceLocation ILEnd, MacroInfo *MI, + MacroArgs *ActualArgs); /// Create a TokenLexer for the specified token stream. If 'OwnsTokens' is /// specified, this takes ownership of the tokens and delete[]'s them when @@ -168,7 +169,7 @@ private: /// first token on the next line. void HandleMicrosoftCommentPaste(Token &Tok); - /// \brief If \arg loc is a FileID and points inside the current macro + /// \brief If \p 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 getExpansionLocForMacroDefLoc(SourceLocation loc) const; diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h index 4ef92f7..c433344 100644 --- a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h +++ b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h @@ -30,6 +30,7 @@ namespace clang { class PragmaHandler; class Scope; class BalancedDelimiterTracker; + class CorrectionCandidateCallback; class DeclGroupRef; class DiagnosticBuilder; class Parser; @@ -163,6 +164,10 @@ class Parser : public CodeCompletionHandler { mutable IdentifierInfo *Ident_final; mutable IdentifierInfo *Ident_override; + // C++ type trait keywords that have can be reverted to identifiers and + // still used as type traits. + llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertableTypeTraits; + OwningPtr<PragmaHandler> AlignHandler; OwningPtr<PragmaHandler> GCCVisibilityHandler; OwningPtr<PragmaHandler> OptionsHandler; @@ -204,6 +209,9 @@ class Parser : public CodeCompletionHandler { /// top-level declaration is finished. SmallVector<TemplateIdAnnotation *, 16> TemplateIds; + /// \brief Identifiers which have been declared within a tentative parse. + SmallVector<IdentifierInfo *, 8> TentativelyDeclaredIdentifiers; + IdentifierInfo *getSEHExceptKeyword(); /// True if we are within an Objective-C container while parsing C-like decls. @@ -244,7 +252,7 @@ public: typedef clang::TypeResult TypeResult; typedef Expr *ExprArg; - typedef ASTMultiPtr<Stmt*> MultiStmtArg; + typedef llvm::MutableArrayRef<Stmt*> MultiStmtArg; typedef Sema::FullExprArg FullExprArg; /// Adorns a ExprResult with Actions to make it an ExprResult @@ -278,6 +286,23 @@ public: /// the EOF was encountered. bool ParseTopLevelDecl(DeclGroupPtrTy &Result); + /// ConsumeToken - Consume the current 'peek token' and lex the next one. + /// This does not work with all kinds of tokens: strings and specific other + /// tokens must be consumed with custom methods below. This returns the + /// location of the consumed token. + SourceLocation ConsumeToken() { + assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() && + !isTokenBrace() && + "Should consume special tokens with Consume*Token"); + + if (Tok.is(tok::code_completion)) + return handleUnexpectedCodeCompletionToken(); + + PrevTokLocation = Tok.getLocation(); + PP.Lex(Tok); + return PrevTokLocation; + } + private: //===--------------------------------------------------------------------===// // Low-Level token peeking and consumption methods. @@ -310,23 +335,6 @@ private: /// For typos, give a fixit to '=' bool isTokenEqualOrEqualTypo(); - /// ConsumeToken - Consume the current 'peek token' and lex the next one. - /// This does not work with all kinds of tokens: strings and specific other - /// tokens must be consumed with custom methods below. This returns the - /// location of the consumed token. - SourceLocation ConsumeToken() { - assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() && - !isTokenBrace() && - "Should consume special tokens with Consume*Token"); - - if (Tok.is(tok::code_completion)) - return handleUnexpectedCodeCompletionToken(); - - PrevTokLocation = Tok.getLocation(); - PP.Lex(Tok); - return PrevTokLocation; - } - /// ConsumeAnyToken - Dispatch to the right Consume* method based on the /// current token type. This should only be used in cases where the type of /// the token really isn't known, e.g. in error recovery. @@ -433,6 +441,34 @@ private: /// #pragma pack... void HandlePragmaPack(); + /// \brief Handle the annotation token produced for + /// #pragma ms_struct... + void HandlePragmaMSStruct(); + + /// \brief Handle the annotation token produced for + /// #pragma align... + void HandlePragmaAlign(); + + /// \brief Handle the annotation token produced for + /// #pragma weak id... + void HandlePragmaWeak(); + + /// \brief Handle the annotation token produced for + /// #pragma weak id = id... + void HandlePragmaWeakAlias(); + + /// \brief Handle the annotation token produced for + /// #pragma redefine_extname... + void HandlePragmaRedefineExtname(); + + /// \brief Handle the annotation token produced for + /// #pragma STDC FP_CONTRACT... + void HandlePragmaFPContract(); + + /// \brief Handle the annotation token produced for + /// #pragma OPENCL EXTENSION... + void HandlePragmaOpenCLExtension(); + /// GetLookAheadToken - This peeks ahead N tokens and returns that token /// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1) /// returns the token after Tok, etc. @@ -445,6 +481,7 @@ private: return PP.LookAhead(N-1); } +public: /// NextToken - This peeks ahead one token and returns it without /// consuming it. const Token &NextToken() { @@ -456,6 +493,7 @@ private: return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue()); } +private: static void setTypeAnnotation(Token &Tok, ParsedType T) { Tok.setAnnotationValue(T.getAsOpaquePtr()); } @@ -478,12 +516,36 @@ private: Tok.setAnnotationValue(ER.get()); } +public: // 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 TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext, + bool NeedType, + CXXScopeSpec &SS, + bool IsNewScope); bool TryAnnotateCXXScopeToken(bool EnteringContext = false); +private: + enum AnnotatedNameKind { + /// Annotation has failed and emitted an error. + ANK_Error, + /// The identifier is a tentatively-declared name. + ANK_TentativeDecl, + /// The identifier is a template name. FIXME: Add an annotation for that. + ANK_TemplateName, + /// The identifier can't be resolved. + ANK_Unresolved, + /// Annotation was successful. + ANK_Success + }; + AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand, + CorrectionCandidateCallback *CCC = 0); + + /// Push a tok::annot_cxxscope token onto the token stream. + void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation); + /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens, /// replacing them with the non-context-sensitive keywords. This returns /// true if the token was replaced. @@ -529,12 +591,15 @@ private: class TentativeParsingAction { Parser &P; Token PrevTok; + size_t PrevTentativelyDeclaredIdentifierCount; unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount; bool isActive; public: explicit TentativeParsingAction(Parser& p) : P(p) { PrevTok = P.Tok; + PrevTentativelyDeclaredIdentifierCount = + P.TentativelyDeclaredIdentifiers.size(); PrevParenCount = P.ParenCount; PrevBracketCount = P.BracketCount; PrevBraceCount = P.BraceCount; @@ -543,6 +608,8 @@ private: } void Commit() { assert(isActive && "Parsing action was finished!"); + P.TentativelyDeclaredIdentifiers.resize( + PrevTentativelyDeclaredIdentifierCount); P.PP.CommitBacktrackedTokens(); isActive = false; } @@ -550,6 +617,8 @@ private: assert(isActive && "Parsing action was finished!"); P.PP.Backtrack(); P.Tok = PrevTok; + P.TentativelyDeclaredIdentifiers.resize( + PrevTentativelyDeclaredIdentifierCount); P.ParenCount = PrevParenCount; P.BracketCount = PrevBracketCount; P.BraceCount = PrevBraceCount; @@ -608,6 +677,7 @@ private: /// \brief Consume any extra semi-colons until the end of the line. void ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST = TST_unspecified); +public: //===--------------------------------------------------------------------===// // Scope manipulation @@ -619,8 +689,8 @@ private: /// the parser will exit the scope. class ParseScope { Parser *Self; - ParseScope(const ParseScope&); // do not implement - ParseScope& operator=(const ParseScope&); // do not implement + ParseScope(const ParseScope &) LLVM_DELETED_FUNCTION; + void operator=(const ParseScope &) LLVM_DELETED_FUNCTION; public: // ParseScope - Construct a new object to manage a scope in the @@ -655,12 +725,13 @@ private: /// ExitScope - Pop a scope off the scope stack. void ExitScope(); +private: /// \brief RAII object used to modify the scope flags for the current scope. class ParseScopeFlags { Scope *CurScope; unsigned OldFlags; - ParseScopeFlags(const ParseScopeFlags &); // do not implement - void operator=(const ParseScopeFlags &); // do not implement + ParseScopeFlags(const ParseScopeFlags &) LLVM_DELETED_FUNCTION; + void operator=(const ParseScopeFlags &) LLVM_DELETED_FUNCTION; public: ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true); @@ -682,6 +753,7 @@ private: SourceRange ParenRange); void CheckNestedObjCContexts(SourceLocation AtLoc); +public: /// SkipUntil - Read tokens until we get to the specified token, then consume /// it (unless DontConsume is true). Because we cannot guarantee that the /// token will ever occur, this skips to the next token, or to some likely @@ -713,6 +785,7 @@ private: /// point for skipping past a simple-declaration. void SkipMalformedDecl(); +private: //===--------------------------------------------------------------------===// // Lexing and parsing of C++ inline methods. @@ -775,9 +848,16 @@ private: void addDecl(Decl *D) { Decls.push_back(D); } }; - /// A list of late parsed attributes. Used by ParseGNUAttributes. - typedef llvm::SmallVector<LateParsedAttribute*, 2> LateParsedAttrList; + // A list of late-parsed attributes. Used by ParseGNUAttributes. + class LateParsedAttrList: public llvm::SmallVector<LateParsedAttribute*, 2> { + public: + LateParsedAttrList(bool PSoon = false) : ParseSoon(PSoon) { } + + bool parseSoon() { return ParseSoon; } + private: + bool ParseSoon; // Are we planning to parse these shortly after creation? + }; /// Contains the lexed tokens of a member function definition /// which needs to be parsed at the end of the class declaration @@ -880,9 +960,9 @@ private: /// any member function declarations or definitions that need to be /// parsed after the corresponding top-level class is complete. struct ParsingClass { - ParsingClass(Decl *TagOrTemplate, bool TopLevelClass) + ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface) : TopLevelClass(TopLevelClass), TemplateScope(false), - TagOrTemplate(TagOrTemplate) { } + IsInterface(IsInterface), TagOrTemplate(TagOrTemplate) { } /// \brief Whether this is a "top-level" class, meaning that it is /// not nested within another class. @@ -893,6 +973,9 @@ private: /// othewise, it is a tag declaration. bool TemplateScope : 1; + /// \brief Whether this class is an __interface. + bool IsInterface : 1; + /// \brief The class or class template whose definition we are parsing. Decl *TagOrTemplate; @@ -919,9 +1002,10 @@ private: Sema::ParsingClassState State; public: - ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass) + ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass, + bool IsInterface) : P(P), Popped(false), - State(P.PushParsingClass(TagOrTemplate, TopLevelClass)) { + State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) { } /// \brief Pop this class of the stack. @@ -1009,7 +1093,7 @@ private: void LateTemplateParser(const FunctionDecl *FD); Sema::ParsingClassState - PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass); + PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface); void DeallocateParsedClasses(ParsingClass *Class); void PopParsingClass(Sema::ParsingClassState); @@ -1145,6 +1229,7 @@ private: Decl *ParseObjCMethodDefinition(); +public: //===--------------------------------------------------------------------===// // C99 6.5: Expressions. @@ -1160,6 +1245,7 @@ private: // Expr that doesn't include commas. ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast); +private: ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc); ExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc); @@ -1174,6 +1260,9 @@ private: bool isAddressOfOperand = false, TypeCastState isTypeCast = NotTypeCast); + /// Returns true if the next token cannot start an expression. + bool isNotExpressionStart(); + /// Returns true if the next token would start a postfix-expression /// suffix. bool isPostfixExpressionSuffixStart() { @@ -1245,6 +1334,8 @@ private: bool *MayBePseudoDestructor = 0, bool IsTypename = false); + void CheckForLParenAfterColonColon(); + //===--------------------------------------------------------------------===// // C++0x 5.1.2: Lambda expressions @@ -1379,8 +1470,16 @@ private: //===--------------------------------------------------------------------===// // C99 6.8: Statements and Blocks. + /// A SmallVector of statements, with stack size 32 (as that is the only one + /// used.) + typedef SmallVector<Stmt*, 32> StmtVector; + /// A SmallVector of expressions, with stack size 12 (the maximum used.) + typedef SmallVector<Expr*, 12> ExprVector; + /// A SmallVector of types. + typedef SmallVector<ParsedType, 12> TypeVector; + StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0) { - StmtVector Stmts(Actions); + StmtVector Stmts; return ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc); } StmtResult ParseStatementOrDeclaration(StmtVector &Stmts, @@ -1399,6 +1498,7 @@ private: StmtResult ParseCompoundStatement(bool isStmtExpr = false); StmtResult ParseCompoundStatement(bool isStmtExpr, unsigned ScopeFlags); + void ParseCompoundStatementLeadingPragmas(); StmtResult ParseCompoundStatementBody(bool isStmtExpr = false); bool ParseParenExprOrCondition(ExprResult &ExprResult, Decl *&DeclResult, @@ -1463,8 +1563,8 @@ private: // C++ 6: Statements and Blocks StmtResult ParseCXXTryBlock(); - StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc); - StmtResult ParseCXXCatchBlock(); + StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry = false); + StmtResult ParseCXXCatchBlock(bool FnCatch = false); //===--------------------------------------------------------------------===// // MS: SEH Statements and Blocks @@ -1578,6 +1678,15 @@ private: /// specifier or if we're not sure. bool isKnownToBeTypeSpecifier(const Token &Tok) const; + /// \brief Return true if we know that we are definitely looking at a + /// decl-specifier, and isn't part of an expression such as a function-style + /// cast. Return false if it's no a decl-specifier, or we're not sure. + bool isKnownToBeDeclarationSpecifier() { + if (getLangOpts().CPlusPlus) + return isCXXDeclarationSpecifier() == TPResult::True(); + return isDeclarationSpecifier(true); + } + /// isDeclarationStatement - Disambiguates between a declaration or an /// expression statement, when parsing function bodies. /// Returns true for declaration, false for expression. @@ -1707,6 +1816,11 @@ private: isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False(), bool *HasMissingTypename = 0); + /// \brief Determine whether an identifier has been tentatively declared as a + /// non-type. Such tentative declarations should not be found to name a type + /// during a tentative parse, but also should not be annotated as a non-type. + bool isTentativelyDeclared(IdentifierInfo *II); + // "Tentative parsing" functions, used for disambiguation. If a parsing error // is encountered they will return TPResult::Error(). // Returning TPResult::True()/False() indicates that the ambiguity was @@ -1724,11 +1838,14 @@ private: TPResult TryParseFunctionDeclarator(); TPResult TryParseBracketDeclarator(); +public: TypeResult ParseTypeName(SourceRange *Range = 0, Declarator::TheContext Context = Declarator::TypeNameContext, AccessSpecifier AS = AS_none, Decl **OwnedType = 0); + +private: void ParseBlockId(SourceLocation CaretLoc); // Check for the start of a C++11 attribute-specifier-seq in a context where @@ -1748,6 +1865,11 @@ private: } void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs); + // Forbid C++11 attributes that appear on certain syntactic + // locations which standard permits but we don't supported yet, + // for example, attributes appertain to decl specifiers. + void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs); + void MaybeParseGNUAttributes(Declarator &D, LateParsedAttrList *LateAttrs = 0) { if (Tok.is(tok::kw___attribute)) { @@ -1769,7 +1891,10 @@ private: void ParseGNUAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc, ParsedAttributes &Attrs, - SourceLocation *EndLoc); + SourceLocation *EndLoc, + IdentifierInfo *ScopeName, + SourceLocation ScopeLoc, + AttributeList::Syntax Syntax); void MaybeParseCXX0XAttributes(Declarator &D) { if (getLangOpts().CPlusPlus0x && isCXX11AttributeSpecifier()) { @@ -1799,6 +1924,7 @@ private: SourceLocation *EndLoc = 0); void ParseCXX11Attributes(ParsedAttributesWithRange &attrs, SourceLocation *EndLoc = 0); + IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc); void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs, @@ -1856,7 +1982,7 @@ private: VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const { return isCXX0XVirtSpecifier(Tok); } - void ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS); + void ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface); bool isCXX0XFinalKeyword() const; @@ -2004,6 +2130,8 @@ private: bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, ParsedType ObjectType, UnqualifiedId &Result); + +public: bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, @@ -2011,6 +2139,7 @@ private: SourceLocation& TemplateKWLoc, UnqualifiedId &Result); +private: //===--------------------------------------------------------------------===// // C++ 14: Templates [temp] diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/DeltaTree.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/DeltaTree.h index f32906a..a6109bf 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/DeltaTree.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/DeltaTree.h @@ -14,6 +14,8 @@ #ifndef CLANG_REWRITE_DELTATREE_H #define CLANG_REWRITE_DELTATREE_H +#include "llvm/Support/Compiler.h" + namespace clang { /// DeltaTree - a multiway search tree (BTree) structure with some fancy @@ -25,7 +27,7 @@ namespace clang { /// as well, without traversing the whole tree. class DeltaTree { void *Root; // "DeltaTreeNode *" - void operator=(const DeltaTree&); // DO NOT IMPLEMENT + void operator=(const DeltaTree &) LLVM_DELETED_FUNCTION; public: DeltaTree(); diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/HTMLRewrite.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/HTMLRewrite.h index 88caf85..88caf85 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/HTMLRewrite.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/HTMLRewrite.h diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/RewriteRope.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/RewriteRope.h index cb3f8a8..9f1bbe5 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/RewriteRope.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/RewriteRope.h @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_REWRITEROPE_H #define LLVM_CLANG_REWRITEROPE_H +#include "llvm/Support/Compiler.h" + #include <cstring> #include <cassert> #include <cstddef> @@ -33,11 +35,11 @@ namespace clang { char Data[1]; // Variable sized. void addRef() { - if (this) ++RefCount; + ++RefCount; } void dropRef() { - if (this && --RefCount == 0) + if (--RefCount == 0) delete [] (char*)this; } }; @@ -63,22 +65,27 @@ namespace clang { RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End) : StrData(Str), StartOffs(Start), EndOffs(End) { - StrData->addRef(); + if (StrData) + StrData->addRef(); } RopePiece(const RopePiece &RP) : StrData(RP.StrData), StartOffs(RP.StartOffs), EndOffs(RP.EndOffs) { - StrData->addRef(); + if (StrData) + StrData->addRef(); } ~RopePiece() { - StrData->dropRef(); + if (StrData) + StrData->dropRef(); } void operator=(const RopePiece &RHS) { if (StrData != RHS.StrData) { - StrData->dropRef(); + if (StrData) + StrData->dropRef(); StrData = RHS.StrData; - StrData->addRef(); + if (StrData) + StrData->addRef(); } StartOffs = RHS.StartOffs; EndOffs = RHS.EndOffs; @@ -148,7 +155,7 @@ namespace clang { class RopePieceBTree { void /*RopePieceBTreeNode*/ *Root; - void operator=(const RopePieceBTree &); // DO NOT IMPLEMENT + void operator=(const RopePieceBTree &) LLVM_DELETED_FUNCTION; public: RopePieceBTree(); RopePieceBTree(const RopePieceBTree &RHS); @@ -191,7 +198,8 @@ public: ~RewriteRope() { // If we had an allocation buffer, drop our reference to it. - AllocBuffer->dropRef(); + if (AllocBuffer) + AllocBuffer->dropRef(); } typedef RopePieceBTree::iterator iterator; diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/Rewriter.h index 5ffd88b..a33ea13 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriter.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/Rewriter.h @@ -16,8 +16,8 @@ #define LLVM_CLANG_REWRITER_H #include "clang/Basic/SourceLocation.h" -#include "clang/Rewrite/DeltaTree.h" -#include "clang/Rewrite/RewriteRope.h" +#include "clang/Rewrite/Core/DeltaTree.h" +#include "clang/Rewrite/Core/RewriteRope.h" #include "llvm/ADT/StringRef.h" #include <cstring> #include <map> @@ -183,7 +183,7 @@ public: /// location was not rewritable, false otherwise. /// /// \param indentNewLines if true new lines in the string are indented - /// using the indentation of the source line in position \arg Loc. + /// using the indentation of the source line in position \p Loc. bool InsertText(SourceLocation Loc, StringRef Str, bool InsertAfter = true, bool indentNewLines = false); diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/TokenRewriter.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/TokenRewriter.h index 894db09..ec0bb5b 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/TokenRewriter.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/TokenRewriter.h @@ -43,8 +43,8 @@ namespace clang { /// OwningPtr<ScratchBuffer> ScratchBuf; - TokenRewriter(const TokenRewriter&); // DO NOT IMPLEMENT - void operator=(const TokenRewriter&); // DO NOT IMPLEMENT. + TokenRewriter(const TokenRewriter &) LLVM_DELETED_FUNCTION; + void operator=(const TokenRewriter &) LLVM_DELETED_FUNCTION; public: /// TokenRewriter - This creates a TokenRewriter for the file with the /// specified FileID. diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/ASTConsumers.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Frontend/ASTConsumers.h index c9c92e3..c9c92e3 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/ASTConsumers.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Frontend/ASTConsumers.h diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/FixItRewriter.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Frontend/FixItRewriter.h index 44f0611..f12a034 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/FixItRewriter.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Frontend/FixItRewriter.h @@ -17,7 +17,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Rewrite/Rewriter.h" +#include "clang/Rewrite/Core/Rewriter.h" #include "clang/Edit/EditedSource.h" namespace clang { diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/FrontendActions.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Frontend/FrontendActions.h index ea876d9..ea876d9 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/FrontendActions.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Frontend/FrontendActions.h diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriters.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Frontend/Rewriters.h index f5ade5a..f5ade5a 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/Rewriters.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Frontend/Rewriters.h diff --git a/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h b/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h index bf35886..2e8b0c0 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h @@ -140,10 +140,10 @@ private: return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1); } - AttributeList(const AttributeList &); // DO NOT IMPLEMENT - void operator=(const AttributeList &); // DO NOT IMPLEMENT - void operator delete(void *); // DO NOT IMPLEMENT - ~AttributeList(); // DO NOT IMPLEMENT + AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION; + void operator=(const AttributeList &) LLVM_DELETED_FUNCTION; + void operator delete(void *) LLVM_DELETED_FUNCTION; + ~AttributeList() LLVM_DELETED_FUNCTION; size_t allocated_size() const; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h index d43aaaf..b128bd8 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -439,9 +439,6 @@ private: /// \brief The availability of this code-completion result. unsigned Availability : 2; - - /// \brief The kind of the parent context. - unsigned ParentKind : 14; /// \brief The name of the parent context. StringRef ParentName; @@ -450,13 +447,13 @@ private: /// entity being completed by this result. const char *BriefComment; - CodeCompletionString(const CodeCompletionString &); // DO NOT IMPLEMENT - CodeCompletionString &operator=(const CodeCompletionString &); // DITTO + CodeCompletionString(const CodeCompletionString &) LLVM_DELETED_FUNCTION; + void operator=(const CodeCompletionString &) LLVM_DELETED_FUNCTION; CodeCompletionString(const Chunk *Chunks, unsigned NumChunks, unsigned Priority, CXAvailabilityKind Availability, const char **Annotations, unsigned NumAnnotations, - CXCursorKind ParentKind, StringRef ParentName, + StringRef ParentName, const char *BriefComment); ~CodeCompletionString() { } @@ -489,11 +486,6 @@ public: /// \brief Retrieve the annotation string specified by \c AnnotationNr. const char *getAnnotation(unsigned AnnotationNr) const; - - /// \brief Retrieve parent context's cursor kind. - CXCursorKind getParentContextKind() const { - return (CXCursorKind)ParentKind; - } /// \brief Retrieve the name of the parent context. StringRef getParentContextName() const { @@ -577,7 +569,6 @@ private: CodeCompletionTUInfo &CCTUInfo; unsigned Priority; CXAvailabilityKind Availability; - CXCursorKind ParentKind; StringRef ParentName; const char *BriefComment; @@ -591,14 +582,14 @@ public: CodeCompletionTUInfo &CCTUInfo) : Allocator(Allocator), CCTUInfo(CCTUInfo), Priority(0), Availability(CXAvailability_Available), - ParentKind(CXCursor_NotImplemented), BriefComment(NULL) { } + BriefComment(NULL) { } CodeCompletionBuilder(CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, unsigned Priority, CXAvailabilityKind Availability) : Allocator(Allocator), CCTUInfo(CCTUInfo), Priority(Priority), Availability(Availability), - ParentKind(CXCursor_NotImplemented), BriefComment(NULL) { } + BriefComment(NULL) { } /// \brief Retrieve the allocator into which the code completion /// strings should be allocated. @@ -642,7 +633,6 @@ public: void addBriefComment(StringRef Comment); - CXCursorKind getParentKind() const { return ParentKind; } StringRef getParentName() const { return ParentName; } }; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h index 792b0c6..0728e87 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h @@ -266,6 +266,7 @@ public: static const TST TST_enum = clang::TST_enum; static const TST TST_union = clang::TST_union; static const TST TST_struct = clang::TST_struct; + static const TST TST_interface = clang::TST_interface; static const TST TST_class = clang::TST_class; static const TST TST_typename = clang::TST_typename; static const TST TST_typeofType = clang::TST_typeofType; @@ -378,11 +379,12 @@ private: } static bool isDeclRep(TST T) { return (T == TST_enum || T == TST_struct || - T == TST_union || T == TST_class); + T == TST_interface || T == TST_union || + T == TST_class); } - DeclSpec(const DeclSpec&); // DO NOT IMPLEMENT - void operator=(const DeclSpec&); // DO NOT IMPLEMENT + DeclSpec(const DeclSpec &) LLVM_DELETED_FUNCTION; + void operator=(const DeclSpec &) LLVM_DELETED_FUNCTION; public: DeclSpec(AttributeFactory &attrFactory) @@ -598,8 +600,7 @@ public: } bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, const LangOptions &Lang, - bool IsTypeSpec); + unsigned &DiagID, const LangOptions &Lang); bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); @@ -781,8 +782,9 @@ private: /// \brief Represents a C++ unqualified-id that has been parsed. class UnqualifiedId { private: - const UnqualifiedId &operator=(const UnqualifiedId &); // DO NOT IMPLEMENT - + UnqualifiedId(const UnqualifiedId &Other) LLVM_DELETED_FUNCTION; + const UnqualifiedId &operator=(const UnqualifiedId &) LLVM_DELETED_FUNCTION; + public: /// \brief Describes the kind of unqualified-id parsed. enum IdKind { @@ -857,17 +859,6 @@ public: UnqualifiedId() : Kind(IK_Identifier), Identifier(0) { } - /// \brief Do not use this copy constructor. It is temporary, and only - /// exists because we are holding FieldDeclarators in a SmallVector when we - /// don't actually need them. - /// - /// FIXME: Kill this copy constructor. - UnqualifiedId(const UnqualifiedId &Other) - : Kind(IK_Identifier), Identifier(Other.Identifier), - StartLocation(Other.StartLocation), EndLocation(Other.EndLocation) { - assert(Other.Kind == IK_Identifier && "Cannot copy non-identifiers"); - } - /// \brief Clear out this unqualified-id, setting it to default (invalid) /// state. void clear() { @@ -1110,7 +1101,7 @@ struct DeclaratorChunk { /// \brief Whether the ref-qualifier (if any) is an lvalue reference. /// Otherwise, it's an rvalue reference. unsigned RefQualifierIsLValueRef : 1; - + /// The type qualifiers: const/volatile/restrict. /// The qualifier bitmask values are the same as in QualType. unsigned TypeQuals : 3; @@ -1125,9 +1116,15 @@ struct DeclaratorChunk { /// specified. unsigned HasTrailingReturnType : 1; + /// The location of the left parenthesis in the source. + unsigned LParenLoc; + /// When isVariadic is true, the location of the ellipsis in the source. unsigned EllipsisLoc; + /// The location of the right parenthesis in the source. + unsigned RParenLoc; + /// NumArgs - This is the number of formal arguments provided for the /// declarator. unsigned NumArgs; @@ -1202,10 +1199,19 @@ struct DeclaratorChunk { bool isKNRPrototype() const { return !hasPrototype && NumArgs != 0; } - + + SourceLocation getLParenLoc() const { + return SourceLocation::getFromRawEncoding(LParenLoc); + } + SourceLocation getEllipsisLoc() const { return SourceLocation::getFromRawEncoding(EllipsisLoc); } + + SourceLocation getRParenLoc() const { + return SourceLocation::getFromRawEncoding(RParenLoc); + } + SourceLocation getExceptionSpecLoc() const { return SourceLocation::getFromRawEncoding(ExceptionSpecLoc); } @@ -1358,11 +1364,13 @@ struct DeclaratorChunk { /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. /// "TheDeclarator" is the declarator that this will be added to. - static DeclaratorChunk getFunction(bool hasProto, bool isVariadic, + static DeclaratorChunk getFunction(bool hasProto, bool isAmbiguous, - SourceLocation EllipsisLoc, + SourceLocation LParenLoc, ParamInfo *ArgInfo, unsigned NumArgs, - unsigned TypeQuals, + SourceLocation EllipsisLoc, + SourceLocation RParenLoc, + unsigned TypeQuals, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation ConstQualifierLoc, diff --git a/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h index c241266..a20480c 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h @@ -124,6 +124,7 @@ public: static DelayedDiagnostic makeDeprecation(SourceLocation Loc, const NamedDecl *D, const ObjCInterfaceDecl *UnknownObjCClass, + const ObjCPropertyDecl *ObjCProperty, StringRef Msg); static DelayedDiagnostic makeAccess(SourceLocation Loc, @@ -193,12 +194,17 @@ public: return DeprecationData.UnknownObjCClass; } + const ObjCPropertyDecl *getObjCProperty() const { + return DeprecationData.ObjCProperty; + } + private: union { /// Deprecation. struct { const NamedDecl *Decl; const ObjCInterfaceDecl *UnknownObjCClass; + const ObjCPropertyDecl *ObjCProperty; const char *Message; size_t MessageLen; } DeprecationData; @@ -220,9 +226,8 @@ class DelayedDiagnosticPool { const DelayedDiagnosticPool *Parent; llvm::SmallVector<DelayedDiagnostic, 4> Diagnostics; - // Do not implement. - DelayedDiagnosticPool(const DelayedDiagnosticPool &other); - DelayedDiagnosticPool &operator=(const DelayedDiagnosticPool &other); + DelayedDiagnosticPool(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION; + void operator=(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION; public: DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {} ~DelayedDiagnosticPool() { diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h index 785bf6a..7a59849 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h @@ -175,7 +175,6 @@ public: 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/Initialization.h b/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h index 77659be..0b0af0c 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h @@ -901,9 +901,9 @@ public: /// \brief Add a constructor-initialization step. /// - /// \arg FromInitList The constructor call is syntactically an initializer + /// \param FromInitList The constructor call is syntactically an initializer /// list. - /// \arg AsInitList The constructor is called as an init list constructor. + /// \param AsInitList The constructor is called as an init list constructor. void AddConstructorInitializationStep(CXXConstructorDecl *Constructor, AccessSpecifier Access, QualType T, diff --git a/contrib/llvm/tools/clang/include/clang/Sema/LocInfoType.h b/contrib/llvm/tools/clang/include/clang/Sema/LocInfoType.h index 93cb8cb..63dfa72 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/LocInfoType.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/LocInfoType.h @@ -55,7 +55,6 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == (TypeClass)LocInfo; } - static bool classof(const LocInfoType *) { return true; } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h new file mode 100644 index 0000000..1513aeb --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -0,0 +1,367 @@ +//===--- MultiplexExternalSemaSource.h - External Sema 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 ExternalSemaSource interface, dispatching to all clients +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H +#define LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H + +#include "clang/Sema/ExternalSemaSource.h" +#include "clang/Sema/Weak.h" + +#include "llvm/ADT/SmallVector.h" + +#include <utility> + +namespace clang { + + class CXXConstructorDecl; + class CXXRecordDecl; + class DeclaratorDecl; + struct ExternalVTableUse; + class LookupResult; + class NamespaceDecl; + class Scope; + class Sema; + class TypedefNameDecl; + class ValueDecl; + class VarDecl; + + +/// \brief An abstract interface that should be implemented by +/// external AST sources that also provide information for semantic +/// analysis. +class MultiplexExternalSemaSource : public ExternalSemaSource { + +private: + llvm::SmallVector<ExternalSemaSource*, 2> Sources; // doesn't own them. + +public: + + ///\brief Constructs a new multiplexing external sema source and appends the + /// given element to it. + /// + ///\param[in] s1 - A non-null (old) ExternalSemaSource. + ///\param[in] s2 - A non-null (new) ExternalSemaSource. + /// + MultiplexExternalSemaSource(ExternalSemaSource& s1, ExternalSemaSource& s2); + + ~MultiplexExternalSemaSource(); + + ///\brief Appends new source to the source list. + /// + ///\param[in] source - An ExternalSemaSource. + /// + void addSource(ExternalSemaSource &source); + + //===--------------------------------------------------------------------===// + // ExternalASTSource. + //===--------------------------------------------------------------------===// + + /// \brief Resolve a declaration ID into a declaration, potentially + /// building a new declaration. + /// + /// This method only needs to be implemented if the AST source ever + /// passes back decl sets as VisibleDeclaration objects. + /// + /// The default implementation of this method is a no-op. + virtual Decl *GetExternalDecl(uint32_t ID); + + /// \brief Resolve a selector ID into a selector. + /// + /// This operation only needs to be implemented if the AST source + /// returns non-zero for GetNumKnownSelectors(). + /// + /// The default implementation of this method is a no-op. + virtual Selector GetExternalSelector(uint32_t ID); + + /// \brief Returns the number of selectors known to the external AST + /// source. + /// + /// The default implementation of this method is a no-op. + virtual uint32_t GetNumExternalSelectors(); + + /// \brief Resolve the offset of a statement in the decl stream into + /// a statement. + /// + /// This operation is meant to be used via a LazyOffsetPtr. It only + /// needs to be implemented if the AST source uses methods like + /// FunctionDecl::setLazyBody when building decls. + /// + /// The default implementation of this method is a no-op. + virtual Stmt *GetExternalDeclStmt(uint64_t Offset); + + /// \brief Resolve the offset of a set of C++ base specifiers in the decl + /// stream into an array of specifiers. + /// + /// The default implementation of this method is a no-op. + virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); + + /// \brief Finds all declarations with the given name in the + /// given context. + /// + /// Generally the final step of this method is either to call + /// SetExternalVisibleDeclsForName or to recursively call lookup on + /// the DeclContext after calling SetExternalVisibleDecls. + /// + /// The default implementation of this method is a no-op. + virtual DeclContextLookupResult + FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); + + /// \brief Ensures that the table of all visible declarations inside this + /// context is up to date. + /// + /// The default implementation of this functino is a no-op. + virtual void completeVisibleDeclsMap(const DeclContext *DC); + + /// \brief Finds all declarations lexically contained within the given + /// DeclContext, after applying an optional filter predicate. + /// + /// \param isKindWeWant a predicate function that returns true if the passed + /// declaration kind is one we are looking for. If NULL, all declarations + /// are returned. + /// + /// \return an indication of whether the load succeeded or failed. + /// + /// The default implementation of this method is a no-op. + virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, + bool (*isKindWeWant)(Decl::Kind), + SmallVectorImpl<Decl*> &Result); + + /// \brief Finds all declarations lexically contained within the given + /// DeclContext. + /// + /// \return true if an error occurred + ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, + SmallVectorImpl<Decl*> &Result) { + return FindExternalLexicalDecls(DC, 0, Result); + } + + template <typename DeclTy> + ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC, + SmallVectorImpl<Decl*> &Result) { + return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result); + } + + /// \brief Get the decls that are contained in a file in the Offset/Length + /// range. \p Length can be 0 to indicate a point at \p Offset instead of + /// a range. + virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length, + SmallVectorImpl<Decl *> &Decls); + + /// \brief Gives the external AST source an opportunity to complete + /// an incomplete type. + virtual void CompleteType(TagDecl *Tag); + + /// \brief Gives the external AST source an opportunity to complete an + /// incomplete Objective-C class. + /// + /// This routine will only be invoked if the "externally completed" bit is + /// set on the ObjCInterfaceDecl via the function + /// \c ObjCInterfaceDecl::setExternallyCompleted(). + virtual void CompleteType(ObjCInterfaceDecl *Class); + + /// \brief Loads comment ranges. + virtual void ReadComments(); + + /// \brief Notify ExternalASTSource that we started deserialization of + /// a decl or type so until FinishedDeserializing is called there may be + /// decls that are initializing. Must be paired with FinishedDeserializing. + /// + /// The default implementation of this method is a no-op. + virtual void StartedDeserializing(); + + /// \brief Notify ExternalASTSource that we finished the deserialization of + /// a decl or type. Must be paired with StartedDeserializing. + /// + /// The default implementation of this method is a no-op. + virtual void FinishedDeserializing(); + + /// \brief Function that will be invoked when we begin parsing a new + /// translation unit involving this external AST source. + /// + /// The default implementation of this method is a no-op. + virtual void StartTranslationUnit(ASTConsumer *Consumer); + + /// \brief Print any statistics that have been gathered regarding + /// the external AST source. + /// + /// The default implementation of this method is a no-op. + virtual void PrintStats(); + + + /// \brief Perform layout on the given record. + /// + /// This routine allows the external AST source to provide an specific + /// layout for a record, overriding the layout that would normally be + /// constructed. It is intended for clients who receive specific layout + /// details rather than source code (such as LLDB). The client is expected + /// to fill in the field offsets, base offsets, virtual base offsets, and + /// complete object size. + /// + /// \param Record The record whose layout is being requested. + /// + /// \param Size The final size of the record, in bits. + /// + /// \param Alignment The final alignment of the record, in bits. + /// + /// \param FieldOffsets The offset of each of the fields within the record, + /// expressed in bits. All of the fields must be provided with offsets. + /// + /// \param BaseOffsets The offset of each of the direct, non-virtual base + /// classes. If any bases are not given offsets, the bases will be laid + /// out according to the ABI. + /// + /// \param VirtualBaseOffsets The offset of each of the virtual base classes + /// (either direct or not). If any bases are not given offsets, the bases will + /// be laid out according to the ABI. + /// + /// \returns true if the record layout was provided, false otherwise. + virtual bool + layoutRecordType(const RecordDecl *Record, + uint64_t &Size, uint64_t &Alignment, + llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets, + llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets); + + /// Return the amount of memory used by memory buffers, breaking down + /// by heap-backed versus mmap'ed memory. + virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const; + + //===--------------------------------------------------------------------===// + // ExternalSemaSource. + //===--------------------------------------------------------------------===// + + /// \brief Initialize the semantic source with the Sema instance + /// being used to perform semantic analysis on the abstract syntax + /// tree. + virtual void InitializeSema(Sema &S); + + /// \brief Inform the semantic consumer that Sema is no longer available. + virtual void ForgetSema(); + + /// \brief Load the contents of the global method pool for a given + /// selector. + virtual void ReadMethodPool(Selector Sel); + + /// \brief Load the set of namespaces that are known to the external source, + /// which will be used during typo correction. + virtual void ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces); + + /// \brief Do last resort, unqualified lookup on a LookupResult that + /// Sema cannot find. + /// + /// \param R a LookupResult that is being recovered. + /// + /// \param S the Scope of the identifier occurrence. + /// + /// \return true to tell Sema to recover using the LookupResult. + virtual bool LookupUnqualified(LookupResult &R, Scope *S); + + /// \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*> &Defs); + + /// \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 MultiplexExternalSemaSource*) { return true; } + //static bool classof(const ExternalSemaSource*) { return true; } +}; + +} // end namespace clang + +#endif // LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Overload.h b/contrib/llvm/tools/clang/include/clang/Sema/Overload.h index d2fc285..65ed781 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Overload.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Overload.h @@ -748,12 +748,14 @@ namespace clang { unsigned NumInlineSequences; char InlineSpace[16 * sizeof(ImplicitConversionSequence)]; - OverloadCandidateSet(const OverloadCandidateSet &); - OverloadCandidateSet &operator=(const OverloadCandidateSet &); - + OverloadCandidateSet(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION; + void operator=(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION; + + void destroyCandidates(); + public: OverloadCandidateSet(SourceLocation Loc) : Loc(Loc), NumInlineSequences(0){} - ~OverloadCandidateSet() { clear(); } + ~OverloadCandidateSet() { destroyCandidates(); } SourceLocation getLocation() const { return Loc; } @@ -808,7 +810,7 @@ namespace clang { void NoteCandidates(Sema &S, OverloadCandidateDisplayKind OCD, llvm::ArrayRef<Expr *> Args, - const char *Opc = 0, + StringRef Opc = "", SourceLocation Loc = SourceLocation()); }; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h b/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h index fb9e368d..e59fb3f 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h @@ -15,7 +15,7 @@ #define LLVM_CLANG_SEMA_OWNERSHIP_H #include "clang/Basic/LLVM.h" -#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" //===----------------------------------------------------------------------===// @@ -30,8 +30,8 @@ namespace clang { class DeclGroupRef; class Expr; class NestedNameSpecifier; + class ParsedTemplateArgument; class QualType; - class Sema; class Stmt; class TemplateName; class TemplateParameterList; @@ -112,96 +112,6 @@ namespace llvm { struct isPodLike<clang::OpaquePtr<T> > { static const bool value = true; }; } - - -// -------------------------- About Move Emulation -------------------------- // -// The smart pointer classes in this file attempt to emulate move semantics -// as they appear in C++0x with rvalue references. Since C++03 doesn't have -// rvalue references, some tricks are needed to get similar results. -// Move semantics in C++0x have the following properties: -// 1) "Moving" means transferring the value of an object to another object, -// similar to copying, but without caring what happens to the old object. -// In particular, this means that the new object can steal the old object's -// resources instead of creating a copy. -// 2) Since moving can modify the source object, it must either be explicitly -// requested by the user, or the modifications must be unnoticeable. -// 3) As such, C++0x moving is only allowed in three contexts: -// * By explicitly using std::move() to request it. -// * From a temporary object, since that object cannot be accessed -// afterwards anyway, thus making the state unobservable. -// * On function return, since the object is not observable afterwards. -// -// To sum up: moving from a named object should only be possible with an -// explicit std::move(), or on function return. Moving from a temporary should -// be implicitly done. Moving from a const object is forbidden. -// -// The emulation is not perfect, and has the following shortcomings: -// * move() is not in namespace std. -// * move() is required on function return. -// * There are difficulties with implicit conversions. -// * Microsoft's compiler must be given the /Za switch to successfully compile. -// -// -------------------------- Implementation -------------------------------- // -// The move emulation relies on the peculiar reference binding semantics of -// C++03: as a rule, a non-const reference may not bind to a temporary object, -// except for the implicit object parameter in a member function call, which -// can refer to a temporary even when not being const. -// The moveable object has five important functions to facilitate moving: -// * A private, unimplemented constructor taking a non-const reference to its -// own class. This constructor serves a two-fold purpose. -// - It prevents the creation of a copy constructor that takes a const -// reference. Temporaries would be able to bind to the argument of such a -// constructor, and that would be bad. -// - Named objects will bind to the non-const reference, but since it's -// private, this will fail to compile. This prevents implicit moving from -// named objects. -// There's also a copy assignment operator for the same purpose. -// * An implicit, non-const conversion operator to a special mover type. This -// type represents the rvalue reference of C++0x. Being a non-const member, -// its implicit this parameter can bind to temporaries. -// * A constructor that takes an object of this mover type. This constructor -// performs the actual move operation. There is an equivalent assignment -// operator. -// There is also a free move() function that takes a non-const reference to -// an object and returns a temporary. Internally, this function uses explicit -// constructor calls to move the value from the referenced object to the return -// value. -// -// There are now three possible scenarios of use. -// * Copying from a const object. Constructor overload resolution will find the -// non-const copy constructor, and the move constructor. The first is not -// viable because the const object cannot be bound to the non-const reference. -// The second fails because the conversion to the mover object is non-const. -// Moving from a const object fails as intended. -// * Copying from a named object. Constructor overload resolution will select -// the non-const copy constructor, but fail as intended, because this -// constructor is private. -// * Copying from a temporary. Constructor overload resolution cannot select -// the non-const copy constructor, because the temporary cannot be bound to -// the non-const reference. It thus selects the move constructor. The -// temporary can be bound to the implicit this parameter of the conversion -// operator, because of the special binding rule. Construction succeeds. -// Note that the Microsoft compiler, as an extension, allows binding -// temporaries against non-const references. The compiler thus selects the -// non-const copy constructor and fails, because the constructor is private. -// Passing /Za (disable extensions) disables this behaviour. -// The free move() function is used to move from a named object. -// -// Note that when passing an object of a different type (the classes below -// have OwningResult and OwningPtr, which should be mixable), you get a problem. -// Argument passing and function return use copy initialization rules. The -// effect of this is that, when the source object is not already of the target -// type, the compiler will first seek a way to convert the source object to the -// target type, and only then attempt to copy the resulting object. This means -// that when passing an OwningResult where an OwningPtr is expected, the -// compiler will first seek a conversion from OwningResult to OwningPtr, then -// copy the OwningPtr. The resulting conversion sequence is: -// OwningResult object -> ResultMover -> OwningResult argument to -// OwningPtr(OwningResult) -> OwningPtr -> PtrMover -> final OwningPtr -// This conversion sequence is too complex to be allowed. Thus the special -// move_* functions, which help the compiler out with some explicit -// conversions. - namespace clang { // Basic class DiagnosticBuilder; @@ -239,6 +149,7 @@ namespace clang { bool isUsable() const { return !Invalid && Val; } PtrTy get() const { return Val; } + // FIXME: Replace with get. PtrTy release() const { return Val; } PtrTy take() const { return Val; } template <typename T> T *takeAs() { return static_cast<T*>(get()); } @@ -282,6 +193,7 @@ namespace clang { void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); return PtrTraits::getFromVoidPointer(VP); } + // FIXME: Replace with get. PtrTy take() const { return get(); } PtrTy release() const { return get(); } template <typename T> T *takeAs() { return static_cast<T*>(get()); } @@ -300,119 +212,11 @@ namespace clang { } }; - /// ASTMultiPtr - A moveable smart pointer to multiple AST nodes. Only owns - /// the individual pointers, not the array holding them. - template <typename PtrTy> class ASTMultiPtr; - - template <class PtrTy> - class ASTMultiPtr { - PtrTy *Nodes; - unsigned Count; - - public: - // Normal copying implicitly defined - ASTMultiPtr() : Nodes(0), Count(0) {} - explicit ASTMultiPtr(Sema &) : Nodes(0), Count(0) {} - ASTMultiPtr(Sema &, PtrTy *nodes, unsigned count) - : Nodes(nodes), Count(count) {} - // Fake mover in Parse/AstGuard.h needs this: - ASTMultiPtr(PtrTy *nodes, unsigned count) : Nodes(nodes), Count(count) {} - - /// Access to the raw pointers. - PtrTy *get() const { return Nodes; } - - /// Access to the count. - unsigned size() const { return Count; } - - PtrTy *release() { - return Nodes; - } - }; - - class ParsedTemplateArgument; - - class ASTTemplateArgsPtr { - ParsedTemplateArgument *Args; - mutable unsigned Count; - - public: - ASTTemplateArgsPtr(Sema &actions, ParsedTemplateArgument *args, - unsigned count) : - Args(args), Count(count) { } - - // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'. - ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) : - Args(Other.Args), Count(Other.Count) { - } - - // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'. - ASTTemplateArgsPtr& operator=(ASTTemplateArgsPtr &Other) { - Args = Other.Args; - Count = Other.Count; - return *this; - } - - ParsedTemplateArgument *getArgs() const { return Args; } - unsigned size() const { return Count; } - - void reset(ParsedTemplateArgument *args, unsigned count) { - Args = args; - Count = count; - } - - const ParsedTemplateArgument &operator[](unsigned Arg) const; - - ParsedTemplateArgument *release() const { - return Args; - } - }; - - /// \brief A small vector that owns a set of AST nodes. - template <class PtrTy, unsigned N = 8> - class ASTOwningVector : public SmallVector<PtrTy, N> { - ASTOwningVector(ASTOwningVector &); // do not implement - ASTOwningVector &operator=(ASTOwningVector &); // do not implement - - public: - explicit ASTOwningVector(Sema &Actions) - { } - - PtrTy *take() { - return &this->front(); - } - - template<typename T> T **takeAs() { return reinterpret_cast<T**>(take()); } - }; - /// An opaque type for threading parsed type information through the /// parser. typedef OpaquePtr<QualType> ParsedType; typedef UnionOpaquePtr<QualType> UnionParsedType; - /// A SmallVector of statements, with stack size 32 (as that is the only one - /// used.) - typedef ASTOwningVector<Stmt*, 32> StmtVector; - /// A SmallVector of expressions, with stack size 12 (the maximum used.) - typedef ASTOwningVector<Expr*, 12> ExprVector; - /// A SmallVector of types. - typedef ASTOwningVector<ParsedType, 12> TypeVector; - - template <class T, unsigned N> inline - ASTMultiPtr<T> move_arg(ASTOwningVector<T, N> &vec) { - return ASTMultiPtr<T>(vec.take(), vec.size()); - } - - // These versions are hopefully no-ops. - template <class T, bool C> - inline ActionResult<T,C> move(ActionResult<T,C> &ptr) { - return ptr; - } - - template <class T> inline - ASTMultiPtr<T>& move(ASTMultiPtr<T> &ptr) { - return ptr; - } - // We can re-use the low bit of expression, statement, base, and // member-initializer pointers for the "invalid" flag of // ActionResult. @@ -438,13 +242,11 @@ namespace clang { typedef ActionResult<Decl*> DeclResult; typedef OpaquePtr<TemplateName> ParsedTemplateTy; - inline Expr *move(Expr *E) { return E; } - inline Stmt *move(Stmt *S) { return S; } - - typedef ASTMultiPtr<Expr*> MultiExprArg; - typedef ASTMultiPtr<Stmt*> MultiStmtArg; - typedef ASTMultiPtr<ParsedType> MultiTypeArg; - typedef ASTMultiPtr<TemplateParameterList*> MultiTemplateParamsArg; + typedef llvm::MutableArrayRef<Expr*> MultiExprArg; + typedef llvm::MutableArrayRef<Stmt*> MultiStmtArg; + typedef llvm::MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr; + typedef llvm::MutableArrayRef<ParsedType> MultiTypeArg; + typedef llvm::MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg; inline ExprResult ExprError() { return ExprResult(true); } inline StmtResult StmtError() { return StmtResult(true); } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h b/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h index 69080ad..94db454 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h @@ -209,11 +209,6 @@ namespace clang { /// Retrieves the range of the given template parameter lists. SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams); - - inline const ParsedTemplateArgument & - ASTTemplateArgsPtr::operator[](unsigned Arg) const { - return Args[Arg]; - } } #endif diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Scope.h b/contrib/llvm/tools/clang/include/clang/Sema/Scope.h index b78556e..fa508cf 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Scope.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Scope.h @@ -82,7 +82,13 @@ public: SwitchScope = 0x800, /// TryScope - This is the scope of a C++ try statement. - TryScope = 0x1000 + TryScope = 0x1000, + + /// FnTryScope - This is the scope of a function-level C++ try scope. + FnTryScope = 0x3000, + + /// FnCatchScope - This is the scope of a function-level C++ catch scope. + FnCatchScope = 0x4000 }; private: /// The parent scope for this scope. This is null for the translation-unit diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h index b4752f5..feda9c9 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h @@ -7,7 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file defines FunctionScopeInfo and BlockScopeInfo. +// This file defines FunctionScopeInfo and its subclasses, which contain +// information about a single function, block, lambda, or method body. // //===----------------------------------------------------------------------===// @@ -21,14 +22,20 @@ namespace clang { +class Decl; class BlockDecl; class CXXMethodDecl; +class ObjCPropertyDecl; class IdentifierInfo; class LabelDecl; class ReturnStmt; class Scope; class SwitchStmt; class VarDecl; +class DeclRefExpr; +class ObjCIvarRefExpr; +class ObjCPropertyRefExpr; +class ObjCMessageExpr; namespace sema { @@ -84,13 +91,10 @@ public: /// \brief Whether this function contains any indirect gotos. bool HasIndirectGoto; - /// 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; + /// A flag that is set when parsing a method that must call super's + /// implementation, such as \c -dealloc, \c -finalize, or any method marked + /// with \c __attribute__((objc_requires_super)). + bool ObjCShouldCallSuper; /// \brief Used to determine if errors occurred in this function or block. DiagnosticErrorTrap ErrorTrap; @@ -113,6 +117,164 @@ public: /// prior to being emitted. SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; +public: + /// Represents a simple identification of a weak object. + /// + /// Part of the implementation of -Wrepeated-use-of-weak. + /// + /// This is used to determine if two weak accesses refer to the same object. + /// Here are some examples of how various accesses are "profiled": + /// + /// Access Expression | "Base" Decl | "Property" Decl + /// :---------------: | :-----------------: | :------------------------------: + /// self.property | self (VarDecl) | property (ObjCPropertyDecl) + /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl) + /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl) + /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl) + /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) + /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) + /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) + /// weakVar | 0 (known) | weakVar (VarDecl) + /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) + /// + /// Objects are identified with only two Decls to make it reasonably fast to + /// compare them. + class WeakObjectProfileTy { + /// The base object decl, as described in the class documentation. + /// + /// The extra flag is "true" if the Base and Property are enough to uniquely + /// identify the object in memory. + /// + /// \sa isExactProfile() + typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy; + BaseInfoTy Base; + + /// The "property" decl, as described in the class documentation. + /// + /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the + /// case of "implicit" properties (regular methods accessed via dot syntax). + const NamedDecl *Property; + + /// Used to find the proper base profile for a given base expression. + static BaseInfoTy getBaseInfo(const Expr *BaseE); + + // For use in DenseMap. + friend class DenseMapInfo; + inline WeakObjectProfileTy(); + static inline WeakObjectProfileTy getSentinel(); + + public: + WeakObjectProfileTy(const ObjCPropertyRefExpr *RE); + WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property); + WeakObjectProfileTy(const DeclRefExpr *RE); + WeakObjectProfileTy(const ObjCIvarRefExpr *RE); + + const NamedDecl *getBase() const { return Base.getPointer(); } + const NamedDecl *getProperty() const { return Property; } + + /// Returns true if the object base specifies a known object in memory, + /// rather than, say, an instance variable or property of another object. + /// + /// Note that this ignores the effects of aliasing; that is, \c foo.bar is + /// considered an exact profile if \c foo is a local variable, even if + /// another variable \c foo2 refers to the same object as \c foo. + /// + /// For increased precision, accesses with base variables that are + /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to + /// be exact, though this is not true for arbitrary variables + /// (foo.prop1.prop2). + bool isExactProfile() const { + return Base.getInt(); + } + + bool operator==(const WeakObjectProfileTy &Other) const { + return Base == Other.Base && Property == Other.Property; + } + + // For use in DenseMap. + // We can't specialize the usual llvm::DenseMapInfo at the end of the file + // because by that point the DenseMap in FunctionScopeInfo has already been + // instantiated. + class DenseMapInfo { + public: + static inline WeakObjectProfileTy getEmptyKey() { + return WeakObjectProfileTy(); + } + static inline WeakObjectProfileTy getTombstoneKey() { + return WeakObjectProfileTy::getSentinel(); + } + + static unsigned getHashValue(const WeakObjectProfileTy &Val) { + typedef std::pair<BaseInfoTy, const NamedDecl *> Pair; + return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base, + Val.Property)); + } + + static bool isEqual(const WeakObjectProfileTy &LHS, + const WeakObjectProfileTy &RHS) { + return LHS == RHS; + } + }; + }; + + /// Represents a single use of a weak object. + /// + /// Stores both the expression and whether the access is potentially unsafe + /// (i.e. it could potentially be warned about). + /// + /// Part of the implementation of -Wrepeated-use-of-weak. + class WeakUseTy { + llvm::PointerIntPair<const Expr *, 1, bool> Rep; + public: + WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {} + + const Expr *getUseExpr() const { return Rep.getPointer(); } + bool isUnsafe() const { return Rep.getInt(); } + void markSafe() { Rep.setInt(false); } + + bool operator==(const WeakUseTy &Other) const { + return Rep == Other.Rep; + } + }; + + /// Used to collect uses of a particular weak object in a function body. + /// + /// Part of the implementation of -Wrepeated-use-of-weak. + typedef SmallVector<WeakUseTy, 4> WeakUseVector; + + /// Used to collect all uses of weak objects in a function body. + /// + /// Part of the implementation of -Wrepeated-use-of-weak. + typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8, + WeakObjectProfileTy::DenseMapInfo> + WeakObjectUseMap; + +private: + /// Used to collect all uses of weak objects in this function body. + /// + /// Part of the implementation of -Wrepeated-use-of-weak. + WeakObjectUseMap WeakObjectUses; + +public: + /// Record that a weak object was accessed. + /// + /// Part of the implementation of -Wrepeated-use-of-weak. + template <typename ExprT> + inline void recordUseOfWeak(const ExprT *E, bool IsRead = true); + + void recordUseOfWeak(const ObjCMessageExpr *Msg, + const ObjCPropertyDecl *Prop); + + /// Record that a given expression is a "safe" access of a weak object (e.g. + /// assigning it to a strong variable.) + /// + /// Part of the implementation of -Wrepeated-use-of-weak. + void markSafeWeakUse(const Expr *E); + + const WeakObjectUseMap &getWeakObjectUses() const { + return WeakObjectUses; + } + void setHasBranchIntoScope() { HasBranchIntoScope = true; } @@ -135,8 +297,7 @@ public: HasBranchProtectedScope(false), HasBranchIntoScope(false), HasIndirectGoto(false), - ObjCShouldCallSuperDealloc(false), - ObjCShouldCallSuperFinalize(false), + ObjCShouldCallSuper(false), ErrorTrap(Diag) { } virtual ~FunctionScopeInfo(); @@ -144,8 +305,6 @@ public: /// \brief Clear out the information in this function scope, making it /// suitable for reuse. void Clear(); - - static bool classof(const FunctionScopeInfo *FSI) { return true; } }; class CapturingScopeInfo : public FunctionScopeInfo { @@ -262,11 +421,7 @@ public: } void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, - Expr *Cpy) { - Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, - Cpy)); - CXXThisCaptureIndex = Captures.size(); - } + Expr *Cpy); /// \brief Determine whether the C++ 'this' is captured. bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } @@ -299,7 +454,6 @@ public: static bool classof(const FunctionScopeInfo *FSI) { return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; } - static bool classof(const CapturingScopeInfo *BSI) { return true; } }; /// \brief Retains information about a block that is currently being parsed. @@ -327,7 +481,6 @@ public: static bool classof(const FunctionScopeInfo *FSI) { return FSI->Kind == SK_Block; } - static bool classof(const BlockScopeInfo *BSI) { return true; } }; class LambdaScopeInfo : public CapturingScopeInfo { @@ -379,15 +532,42 @@ public: void finishedExplicitCaptures() { NumExplicitCaptures = Captures.size(); } - - static bool classof(const FunctionScopeInfo *FSI) { + + static bool classof(const FunctionScopeInfo *FSI) { return FSI->Kind == SK_Lambda; } - static bool classof(const LambdaScopeInfo *BSI) { return true; } - }; + +FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy() + : Base(0, false), Property(0) {} + +FunctionScopeInfo::WeakObjectProfileTy +FunctionScopeInfo::WeakObjectProfileTy::getSentinel() { + FunctionScopeInfo::WeakObjectProfileTy Result; + Result.Base.setInt(true); + return Result; +} + +template <typename ExprT> +void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { + assert(E); + WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)]; + Uses.push_back(WeakUseTy(E, IsRead)); } + +inline void +CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, + QualType CaptureType, Expr *Cpy) { + Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, + Cpy)); + CXXThisCaptureIndex = Captures.size(); + + if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this)) + LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size()); } +} // end namespace sema +} // end namespace clang + #endif diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h index acc88c0..9b572d8 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h @@ -187,9 +187,16 @@ typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>, /// Sema - This implements semantic analysis and AST building for C. class Sema { - Sema(const Sema&); // DO NOT IMPLEMENT - void operator=(const Sema&); // DO NOT IMPLEMENT + Sema(const Sema &) LLVM_DELETED_FUNCTION; + void operator=(const Sema &) LLVM_DELETED_FUNCTION; mutable const TargetAttributesSema* TheTargetAttributesSema; + + ///\brief Source of additional semantic information. + ExternalSemaSource *ExternalSource; + + ///\brief Whether Sema has generated a multiplexer and has to delete it. + bool isMultiplexExternalSource; + public: typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; typedef OpaquePtr<TemplateName> TemplateTy; @@ -208,9 +215,6 @@ public: /// \brief Flag indicating whether or not to collect detailed statistics. bool CollectStats; - /// \brief Source of additional semantic information. - ExternalSemaSource *ExternalSource; - /// \brief Code-completion consumer. CodeCompleteConsumer *CodeCompleter; @@ -234,6 +238,12 @@ public: /// VisContext - Manages the stack for \#pragma GCC visibility. void *VisContext; // Really a "PragmaVisStack*" + /// \brief Flag indicating if Sema is building a recovery call expression. + /// + /// This flag is used to avoid building recovery call expressions + /// if Sema is already doing so, which would cause infinite recursions. + bool IsBuildingRecoveryCallExpr; + /// ExprNeedsCleanups - True if the current evaluation context /// requires cleanups to be run at its conclusion. bool ExprNeedsCleanups; @@ -456,6 +466,26 @@ public: } }; + /// \brief RAII object to handle the state changes required to synthesize + /// a function body. + class SynthesizedFunctionScope { + Sema &S; + Sema::ContextRAII SavedContext; + + public: + SynthesizedFunctionScope(Sema &S, DeclContext *DC) + : S(S), SavedContext(S, DC) + { + S.PushFunctionScope(); + S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); + } + + ~SynthesizedFunctionScope() { + S.PopExpressionEvaluationContext(); + S.PopFunctionScopeInfo(); + } + }; + /// WeakUndeclaredIdentifiers - Identifiers contained in /// \#pragma weak before declared. rare. may alias another /// identifier, declared or undeclared @@ -729,6 +759,20 @@ public: /// should not be used elsewhere. void EmitCurrentDiagnostic(unsigned DiagID); + /// Records and restores the FP_CONTRACT state on entry/exit of compound + /// statements. + class FPContractStateRAII { + public: + FPContractStateRAII(Sema& S) + : S(S), OldFPContractState(S.FPFeatures.fp_contract) {} + ~FPContractStateRAII() { + S.FPFeatures.fp_contract = OldFPContractState; + } + private: + Sema& S; + bool OldFPContractState : 1; + }; + public: Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind = TU_Complete, @@ -750,6 +794,14 @@ public: ASTContext &getASTContext() const { return Context; } ASTConsumer &getASTConsumer() const { return Consumer; } ASTMutationListener *getASTMutationListener() const; + ExternalSemaSource* getExternalSource() const { return ExternalSource; } + + ///\brief Registers an external source. If an external source already exists, + /// creates a multiplex external source and appends to it. + /// + ///\param[in] E - A non-null external sema source. + /// + void addExternalSource(ExternalSemaSource *E); void PrintStats() const; @@ -1203,7 +1255,7 @@ public: assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate); return Kind == NC_TypeTemplate? TNK_Type_template : TNK_Function_template; } -}; + }; /// \brief Perform name lookup on the given name, classifying it based on /// the results of name lookup and the following token. @@ -1223,11 +1275,19 @@ public: /// /// \param NextToken The token following the identifier. Used to help /// disambiguate the name. + /// + /// \param IsAddressOfOperand True if this name is the operand of a unary + /// address of ('&') expression, assuming it is classified as an + /// expression. + /// + /// \param CCC The correction callback, if typo correction is desired. NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, - const Token &NextToken); + const Token &NextToken, + bool IsAddressOfOperand, + CorrectionCandidateCallback *CCC = 0); Decl *ActOnDeclarator(Scope *S, Declarator &D); @@ -1265,6 +1325,7 @@ public: MultiTemplateParamsArg TemplateParamLists, bool &AddToScope); bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); + void checkVoidParamDecl(ParmVarDecl *Param); bool CheckConstexprFunctionDecl(const FunctionDecl *FD); bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body); @@ -1293,7 +1354,6 @@ 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); @@ -1642,7 +1702,7 @@ public: /// \brief Checks availability of the function depending on the current /// function context.Inside an unavailable function,unavailability is ignored. /// - /// \returns true if \arg FD is unavailable and current context is inside + /// \returns true if \p FD is unavailable and current context is inside /// an available function, false otherwise. bool isFunctionConsideredUnavailable(FunctionDecl *FD); @@ -1866,8 +1926,7 @@ public: llvm::ArrayRef<Expr *> Args, TemplateArgumentListInfo *ExplicitTemplateArgs, OverloadCandidateSet& CandidateSet, - bool PartialOverloading = false, - bool StdNamespaceIsAssociated = false); + bool PartialOverloading = false); // Emit as a 'note' the specific overload candidate void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType()); @@ -1916,6 +1975,30 @@ public: OverloadCandidateSet &CandidateSet, bool PartialOverloading = false); + // An enum used to represent the different possible results of building a + // range-based for loop. + enum ForRangeStatus { + FRS_Success, + FRS_NoViableFunction, + FRS_DiagnosticIssued + }; + + // An enum to represent whether something is dealing with a call to begin() + // or a call to end() in a range-based for loop. + enum BeginEndFunction { + BEF_begin, + BEF_end + }; + + ForRangeStatus BuildForRangeBeginEndCall(Scope *S, SourceLocation Loc, + SourceLocation RangeLoc, + VarDecl *Decl, + BeginEndFunction BEF, + const DeclarationNameInfo &NameInfo, + LookupResult &MemberLookup, + OverloadCandidateSet *CandidateSet, + Expr *Range, ExprResult *CallExpr); + ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, @@ -1924,6 +2007,12 @@ public: Expr *ExecConfig, bool AllowTypoCorrection=true); + bool buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, + Expr **Args, unsigned NumArgs, + SourceLocation RParenLoc, + OverloadCandidateSet *CandidateSet, + ExprResult *Result); + ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned Opc, const UnresolvedSetImpl &Fns, @@ -2130,8 +2219,7 @@ public: void ArgumentDependentLookup(DeclarationName Name, bool Operator, SourceLocation Loc, llvm::ArrayRef<Expr *> Args, - ADLResult &Functions, - bool StdNamespaceIsAssociated = false); + ADLResult &Functions); void LookupVisibleDecls(Scope *S, LookupNameKind Kind, VisibleDeclConsumer &Consumer, @@ -2148,7 +2236,8 @@ public: bool EnteringContext = false, const ObjCObjectPointerType *OPT = 0); - void FindAssociatedClassesAndNamespaces(llvm::ArrayRef<Expr *> Args, + void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, + llvm::ArrayRef<Expr *> Args, AssociatedNamespaceSet &AssociatedNamespaces, AssociatedClassSet &AssociatedClasses); @@ -2249,13 +2338,7 @@ public: void CollectImmediateProperties(ObjCContainerDecl *CDecl, llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap, llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap); - - - /// LookupPropertyDecl - Looks up a property in the current class and all - /// its protocols. - ObjCPropertyDecl *LookupPropertyDecl(const ObjCContainerDecl *CDecl, - IdentifierInfo *II); - + /// Called by ActOnProperty to handle \@property declarations in /// class extensions. Decl *HandlePropertyInClassExtension(Scope *S, @@ -2399,7 +2482,7 @@ public: FullExprArg(const FullExprArg& Other) : E(Other.E) {} ExprResult release() { - return move(E); + return E; } Expr *get() const { return E; } @@ -2502,15 +2585,28 @@ public: SourceLocation RParenLoc); StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body); + enum BuildForRangeKind { + /// Initial building of a for-range statement. + BFRK_Build, + /// Instantiation or recovery rebuild of a for-range statement. Don't + /// attempt any typo-correction. + BFRK_Rebuild, + /// Determining whether a for-range statement could be built. Avoid any + /// unnecessary or irreversible actions. + BFRK_Check + }; + StmtResult ActOnCXXForRangeStmt(SourceLocation ForLoc, Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + BuildForRangeKind Kind); StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, Stmt *RangeDecl, Stmt *BeginEndDecl, Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + BuildForRangeKind Kind); StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body); StmtResult ActOnGotoStmt(SourceLocation GotoLoc, @@ -2528,21 +2624,19 @@ public: StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); - StmtResult ActOnAsmStmt(SourceLocation AsmLoc, - bool IsSimple, bool IsVolatile, - unsigned NumOutputs, unsigned NumInputs, - IdentifierInfo **Names, - MultiExprArg Constraints, - MultiExprArg Exprs, - Expr *AsmString, - MultiExprArg Clobbers, - SourceLocation RParenLoc, - bool MSAsm = false); + StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, + bool IsVolatile, unsigned NumOutputs, + unsigned NumInputs, IdentifierInfo **Names, + MultiExprArg Constraints, MultiExprArg Exprs, + Expr *AsmString, MultiExprArg Clobbers, + SourceLocation RParenLoc); - StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, - SourceLocation LBraceLoc, - ArrayRef<Token> AsmToks, - SourceLocation EndLoc); + NamedDecl *LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc, + unsigned &Size); + bool LookupInlineAsmField(StringRef Base, StringRef Member, + unsigned &Offset, SourceLocation AsmLoc); + StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, + ArrayRef<Token> AsmToks, SourceLocation EndLoc); VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, SourceLocation StartLoc, @@ -2639,7 +2733,8 @@ public: void EmitDeprecationWarning(NamedDecl *D, StringRef Message, SourceLocation Loc, - const ObjCInterfaceDecl *UnknownObjCClass=0); + const ObjCInterfaceDecl *UnknownObjCClass, + const ObjCPropertyDecl *ObjCProperty); void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); @@ -2663,7 +2758,10 @@ public: void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = 0, bool IsDecltype = false); - + enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl }; + void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, + ReuseLambdaContextDecl_t, + bool IsDecltype = false); void PopExpressionEvaluationContext(); void DiscardCleanupsInEvaluationContext(); @@ -2815,7 +2913,8 @@ public: bool HasTrailingLParen); ExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, - const DeclarationNameInfo &NameInfo); + const DeclarationNameInfo &NameInfo, + bool IsAddressOfOperand); ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, @@ -3279,18 +3378,11 @@ public: // Pointer to allow copying Sema *Self; // We order exception specifications thus: - // noexcept is the most restrictive, but is only used in C++0x. + // noexcept is the most restrictive, but is only used in C++11. // throw() comes next. // Then a throw(collected exceptions) - // Finally no specification. + // Finally no specification, which is expressed as noexcept(false). // throw(...) is used instead if any called function uses it. - // - // If this exception specification cannot be known yet (for instance, - // because this is the exception specification for a defaulted default - // constructor and we haven't finished parsing the deferred parts of the - // class yet), the C++0x standard does not specify how to behave. We - // record this as an 'unknown' exception specification, which overrules - // any other specification (even 'none', to keep this rule simple). ExceptionSpecificationType ComputedEST; llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen; SmallVector<QualType, 4> Exceptions; @@ -3330,8 +3422,17 @@ public: /// computed exception specification. void getEPI(FunctionProtoType::ExtProtoInfo &EPI) const { EPI.ExceptionSpecType = getExceptionSpecType(); - EPI.NumExceptions = size(); - EPI.Exceptions = data(); + if (EPI.ExceptionSpecType == EST_Dynamic) { + EPI.NumExceptions = size(); + EPI.Exceptions = data(); + } else if (EPI.ExceptionSpecType == EST_None) { + /// C++11 [except.spec]p14: + /// The exception-specification is noexcept(false) if the set of + /// potential exceptions of the special member function contains "any" + EPI.ExceptionSpecType = EST_ComputedNoexcept; + EPI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(), + tok::kw_false).take(); + } } FunctionProtoType::ExtProtoInfo getEPI() const { FunctionProtoType::ExtProtoInfo EPI; @@ -3515,7 +3616,7 @@ public: bool CompleteConstructorCall(CXXConstructorDecl *Constructor, MultiExprArg ArgsPtr, SourceLocation Loc, - ASTOwningVector<Expr*> &ConvertedArgs, + SmallVectorImpl<Expr*> &ConvertedArgs, bool AllowExplicit = false); ParsedType getDestructorName(SourceLocation TildeLoc, @@ -3661,7 +3762,7 @@ public: SourceLocation PlacementRParen, SourceRange TypeIdParens, Declarator &D, Expr *Initializer); - ExprResult BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, + ExprResult BuildCXXNew(SourceRange Range, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, @@ -3991,7 +4092,8 @@ public: /// \brief Create a new lambda closure type. CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange, - bool KnownDependent = false); + TypeSourceInfo *Info, + bool KnownDependent); /// \brief Start the definition of a lambda expression. CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class, @@ -4300,7 +4402,7 @@ public: SourceLocation RParenLoc, bool Failed); - FriendDecl *CheckFriendTypeDecl(SourceLocation Loc, + FriendDecl *CheckFriendTypeDecl(SourceLocation LocStart, SourceLocation FriendLoc, TypeSourceInfo *TSInfo); Decl *ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS, @@ -4622,8 +4724,6 @@ public: /// \brief Parsed an elaborated-type-specifier that refers to a template-id, /// such as \c class T::template apply<U>. - /// - /// \param TUK TypeResult ActOnTagTemplateIdType(TagUseKind TUK, TypeSpecifierType TagSpec, SourceLocation TagLoc, @@ -4799,7 +4899,8 @@ public: TemplateArgument &Converted, CheckTemplateArgumentKind CTAK = CTAK_Specified); bool CheckTemplateArgument(TemplateTemplateParmDecl *Param, - const TemplateArgumentLoc &Arg); + const TemplateArgumentLoc &Arg, + unsigned ArgumentPackIndex); ExprResult BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, @@ -5246,6 +5347,8 @@ public: enum TemplateDeductionResult { /// \brief Template argument deduction was successful. TDK_Success = 0, + /// \brief The declaration was invalid; do nothing. + TDK_Invalid, /// \brief Template argument deduction exceeded the maximum template /// instantiation depth (which has already been diagnosed). TDK_InstantiationDepth, @@ -5681,10 +5784,10 @@ public: bool CheckInstantiationDepth(SourceLocation PointOfInstantiation, SourceRange InstantiationRange); - InstantiatingTemplate(const InstantiatingTemplate&); // not implemented + InstantiatingTemplate(const InstantiatingTemplate&) LLVM_DELETED_FUNCTION; InstantiatingTemplate& - operator=(const InstantiatingTemplate&); // not implemented + operator=(const InstantiatingTemplate&) LLVM_DELETED_FUNCTION; }; void PrintInstantiationStack(); @@ -6016,7 +6119,7 @@ public: /// Ensure attributes are consistent with type. /// \param [in, out] Attributes The attributes to check; they will - /// be modified to be consistent with \arg PropertyTy. + /// be modified to be consistent with \p PropertyTy. void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, unsigned &Attributes, @@ -6252,8 +6355,7 @@ public: /// ActOnPragmaOptionsAlign - Called on well formed \#pragma options align. void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, - SourceLocation PragmaLoc, - SourceLocation KindLoc); + SourceLocation PragmaLoc); enum PragmaPackKind { PPK_Default, // #pragma pack([n]) @@ -6748,6 +6850,7 @@ public: /// might create an obvious retain cycle. void checkRetainCycles(ObjCMessageExpr *msg); void checkRetainCycles(Expr *receiver, Expr *argument); + void checkRetainCycles(VarDecl *Var, Expr *Init); /// checkUnsafeAssigns - Check whether +1 expr is being assigned /// to weak/__unsafe_unretained type. @@ -6763,6 +6866,7 @@ public: /// \return true iff there were any incompatible types. bool CheckMessageArgumentTypes(QualType ReceiverType, Expr **Args, unsigned NumArgs, Selector Sel, + ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, @@ -7210,6 +7314,14 @@ public: } AvailabilityResult getCurContextAvailability() const; + + const DeclContext *getCurObjCLexicalContext() const { + const DeclContext *DC = getCurLexicalContext(); + // A category implicitly has the attribute of the interface. + if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC)) + DC = CatD->getClassInterface(); + return DC; + } }; /// \brief RAII object that enters a new expression evaluation context. @@ -7225,6 +7337,15 @@ public: Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl, IsDecltype); } + EnterExpressionEvaluationContext(Sema &Actions, + Sema::ExpressionEvaluationContext NewContext, + Sema::ReuseLambdaContextDecl_t, + bool IsDecltype = false) + : Actions(Actions) { + Actions.PushExpressionEvaluationContext(NewContext, + Sema::ReuseLambdaContextDecl, + IsDecltype); + } ~EnterExpressionEvaluationContext() { Actions.PopExpressionEvaluationContext(); diff --git a/contrib/llvm/tools/clang/include/clang/Sema/SemaConsumer.h b/contrib/llvm/tools/clang/include/clang/Sema/SemaConsumer.h index 139cce8..676646a 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/SemaConsumer.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/SemaConsumer.h @@ -42,7 +42,6 @@ namespace clang { static bool classof(const ASTConsumer *Consumer) { return Consumer->SemaConsumer; } - static bool classof(const SemaConsumer *) { return true; } }; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Template.h b/contrib/llvm/tools/clang/include/clang/Sema/Template.h index 273374d..bbccd25 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Template.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Template.h @@ -239,8 +239,9 @@ namespace clang { unsigned NumArgsInPartiallySubstitutedPack; // This class is non-copyable - LocalInstantiationScope(const LocalInstantiationScope &); - LocalInstantiationScope &operator=(const LocalInstantiationScope &); + LocalInstantiationScope( + const LocalInstantiationScope &) LLVM_DELETED_FUNCTION; + void operator=(const LocalInstantiationScope &) LLVM_DELETED_FUNCTION; public: LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) diff --git a/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h b/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h index 4c2d876..251a659 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h @@ -19,7 +19,6 @@ namespace clang { -class ASTContext; class TemplateArgumentList; namespace sema { @@ -28,9 +27,6 @@ namespace sema { /// deduction, whose success or failure was described by a /// TemplateDeductionResult value. class TemplateDeductionInfo { - /// \brief The context in which the template arguments are stored. - ASTContext &Context; - /// \brief The deduced template argument list. /// TemplateArgumentList *Deduced; @@ -46,17 +42,12 @@ class TemplateDeductionInfo { /// SFINAE while performing template argument deduction. SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; - // do not implement these - TemplateDeductionInfo(const TemplateDeductionInfo&); - TemplateDeductionInfo &operator=(const TemplateDeductionInfo&); + TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; + void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; public: - TemplateDeductionInfo(ASTContext &Context, SourceLocation Loc) - : Context(Context), Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false) { } - - ~TemplateDeductionInfo() { - // FIXME: if (Deduced) Deduced->Destroy(Context); - } + TemplateDeductionInfo(SourceLocation Loc) + : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false) { } /// \brief Returns the location at which template argument is /// occurring. @@ -83,7 +74,6 @@ public: /// \brief Provide a new template argument list that contains the /// results of template argument deduction. void reset(TemplateArgumentList *NewDeduced) { - // FIXME: if (Deduced) Deduced->Destroy(Context); Deduced = NewDeduced; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h b/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h index a8f6e11..2b4a9e6 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h @@ -170,6 +170,17 @@ public: return CorrectionDecls.size() > 1; } + void setCorrectionRange(CXXScopeSpec* SS, + const DeclarationNameInfo &TypoName) { + CorrectionRange.setBegin(CorrectionNameSpec && SS ? SS->getBeginLoc() + : TypoName.getLoc()); + CorrectionRange.setEnd(TypoName.getLoc()); + } + + SourceRange getCorrectionRange() const { + return CorrectionRange; + } + typedef llvm::SmallVector<NamedDecl*, 1>::iterator decl_iterator; decl_iterator begin() { return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); @@ -193,6 +204,7 @@ private: unsigned CharDistance; unsigned QualifierDistance; unsigned CallbackDistance; + SourceRange CorrectionRange; }; /// @brief Base class for callback objects used by Sema::CorrectTypo to check diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h index dbe6e5a..8c58fb2 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h @@ -126,7 +126,13 @@ namespace clang { /// \brief The number of predefined identifier IDs. const unsigned int NUM_PREDEF_IDENT_IDS = 1; + + /// \brief An ID number that refers to a macro in an AST file. + typedef uint32_t MacroID; + /// \brief The number of predefined macro IDs. + const unsigned int NUM_PREDEF_MACRO_IDS = 1; + /// \brief An ID number that refers to an ObjC selector in an AST file. typedef uint32_t SelectorID; @@ -210,7 +216,71 @@ namespace clang { SUBMODULE_BLOCK_ID, /// \brief The block containing comments. - COMMENTS_BLOCK_ID + COMMENTS_BLOCK_ID, + + /// \brief The control block, which contains all of the + /// information that needs to be validated prior to committing + /// to loading the AST file. + CONTROL_BLOCK_ID, + + /// \brief The block of input files, which were used as inputs + /// to create this AST file. + /// + /// This block is part of the control block. + INPUT_FILES_BLOCK_ID + }; + + /// \brief Record types that occur within the control block. + enum ControlRecordTypes { + /// \brief AST file metadata, including the AST file version number + /// and information about the compiler used to build this AST file. + METADATA = 1, + + /// \brief Record code for the list of other AST files imported by + /// this AST file. + IMPORTS = 2, + + /// \brief Record code for the language options table. + /// + /// The record with this code contains the contents of the + /// LangOptions structure. We serialize the entire contents of + /// the structure, and let the reader decide which options are + /// actually important to check. + LANGUAGE_OPTIONS = 3, + + /// \brief Record code for the target options table. + TARGET_OPTIONS = 4, + + /// \brief Record code for the original file that was used to + /// generate the AST file, including both its file ID and its + /// name. + ORIGINAL_FILE = 5, + + /// \brief The directory that the PCH was originally created in. + ORIGINAL_PCH_DIR = 6, + + /// \brief Offsets into the input-files block where input files + /// reside. + INPUT_FILE_OFFSETS = 7, + + /// \brief Record code for the diagnostic options table. + DIAGNOSTIC_OPTIONS = 8, + + /// \brief Record code for the filesystem options table. + FILE_SYSTEM_OPTIONS = 9, + + /// \brief Record code for the headers search options table. + HEADER_SEARCH_OPTIONS = 10, + + /// \brief Record code for the preprocessor options table. + PREPROCESSOR_OPTIONS = 11 + }; + + /// \brief Record types that occur within the input-files block + /// inside the control block. + enum InputFileRecordTypes { + /// \brief An input file. + INPUT_FILE = 1 }; /// \brief Record types that occur within the AST block itself. @@ -241,25 +311,13 @@ namespace clang { /// reserved for the translation unit declaration. DECL_OFFSET = 2, - /// \brief Record code for the language options table. - /// - /// The record with this code contains the contents of the - /// LangOptions structure. We serialize the entire contents of - /// the structure, and let the reader decide which options are - /// actually important to check. - LANGUAGE_OPTIONS = 3, - - /// \brief AST file metadata, including the AST file version number - /// and the target triple used to build the AST file. - METADATA = 4, - /// \brief Record code for the table of offsets of each /// identifier ID. /// /// The offset table contains offsets into the blob stored in /// the IDENTIFIER_TABLE record. Each offset points to the /// NULL-terminated string that corresponds to that identifier. - IDENTIFIER_OFFSET = 5, + IDENTIFIER_OFFSET = 3, /// \brief Record code for the identifier table. /// @@ -273,7 +331,7 @@ namespace clang { /// between offsets (for unresolved identifier IDs) and /// IdentifierInfo pointers (for already-resolved identifier /// IDs). - IDENTIFIER_TABLE = 6, + IDENTIFIER_TABLE = 4, /// \brief Record code for the array of external definitions. /// @@ -283,7 +341,7 @@ namespace clang { /// reported to the AST consumer after the AST file has been /// read, since their presence can affect the semantics of the /// program (e.g., for code generation). - EXTERNAL_DEFINITIONS = 7, + EXTERNAL_DEFINITIONS = 5, /// \brief Record code for the set of non-builtin, special /// types. @@ -292,33 +350,33 @@ namespace clang { /// that are constructed during semantic analysis (e.g., /// __builtin_va_list). The SPECIAL_TYPE_* constants provide /// offsets into this record. - SPECIAL_TYPES = 8, + SPECIAL_TYPES = 6, /// \brief Record code for the extra statistics we gather while /// generating an AST file. - STATISTICS = 9, + STATISTICS = 7, /// \brief Record code for the array of tentative definitions. - TENTATIVE_DEFINITIONS = 10, + TENTATIVE_DEFINITIONS = 8, /// \brief Record code for the array of locally-scoped external /// declarations. - LOCALLY_SCOPED_EXTERNAL_DECLS = 11, + LOCALLY_SCOPED_EXTERNAL_DECLS = 9, /// \brief Record code for the table of offsets into the /// Objective-C method pool. - SELECTOR_OFFSETS = 12, + SELECTOR_OFFSETS = 10, /// \brief Record code for the Objective-C method pool, - METHOD_POOL = 13, + METHOD_POOL = 11, /// \brief The value of the next __COUNTER__ to dispense. /// [PP_COUNTER_VALUE, Val] - PP_COUNTER_VALUE = 14, + PP_COUNTER_VALUE = 12, /// \brief Record code for the table of offsets into the block /// of source-location information. - SOURCE_LOCATION_OFFSETS = 15, + SOURCE_LOCATION_OFFSETS = 13, /// \brief Record code for the set of source location entries /// that need to be preloaded by the AST reader. @@ -326,153 +384,138 @@ namespace clang { /// This set contains the source location entry for the /// predefines buffer and for any file entries that need to be /// preloaded. - SOURCE_LOCATION_PRELOADS = 16, - - /// \brief Record code for the stat() cache. - STAT_CACHE = 17, + SOURCE_LOCATION_PRELOADS = 14, /// \brief Record code for the set of ext_vector type names. - EXT_VECTOR_DECLS = 18, - - /// \brief Record code for the original file that was used to - /// generate the AST file. - ORIGINAL_FILE_NAME = 19, - - /// \brief Record code for the file ID of the original file used to - /// generate the AST file. - ORIGINAL_FILE_ID = 20, - - /// \brief Record code for the version control branch and revision - /// information of the compiler used to build this AST file. - VERSION_CONTROL_BRANCH_REVISION = 21, + EXT_VECTOR_DECLS = 16, /// \brief Record code for the array of unused file scoped decls. - UNUSED_FILESCOPED_DECLS = 22, + UNUSED_FILESCOPED_DECLS = 17, /// \brief Record code for the table of offsets to entries in the /// preprocessing record. - PPD_ENTITIES_OFFSETS = 23, + PPD_ENTITIES_OFFSETS = 18, /// \brief Record code for the array of VTable uses. - VTABLE_USES = 24, + VTABLE_USES = 19, /// \brief Record code for the array of dynamic classes. - DYNAMIC_CLASSES = 25, - - /// \brief Record code for the list of other AST files imported by - /// this AST file. - IMPORTS = 26, + DYNAMIC_CLASSES = 20, /// \brief Record code for referenced selector pool. - REFERENCED_SELECTOR_POOL = 27, + REFERENCED_SELECTOR_POOL = 21, /// \brief Record code for an update to the TU's lexically contained /// declarations. - TU_UPDATE_LEXICAL = 28, + TU_UPDATE_LEXICAL = 22, /// \brief Record code for the array describing the locations (in the /// LOCAL_REDECLARATIONS record) of the redeclaration chains, indexed by /// the first known ID. - LOCAL_REDECLARATIONS_MAP = 29, + LOCAL_REDECLARATIONS_MAP = 23, /// \brief Record code for declarations that Sema keeps references of. - SEMA_DECL_REFS = 30, + SEMA_DECL_REFS = 24, /// \brief Record code for weak undeclared identifiers. - WEAK_UNDECLARED_IDENTIFIERS = 31, + WEAK_UNDECLARED_IDENTIFIERS = 25, /// \brief Record code for pending implicit instantiations. - PENDING_IMPLICIT_INSTANTIATIONS = 32, + PENDING_IMPLICIT_INSTANTIATIONS = 26, /// \brief Record code for a decl replacement block. /// /// If a declaration is modified after having been deserialized, and then /// written to a dependent AST file, its ID and offset must be added to /// the replacement block. - DECL_REPLACEMENTS = 33, + DECL_REPLACEMENTS = 27, /// \brief Record code for an update to a decl context's lookup table. /// /// In practice, this should only be used for the TU and namespaces. - UPDATE_VISIBLE = 34, + UPDATE_VISIBLE = 28, /// \brief Record for offsets of DECL_UPDATES records for declarations /// that were modified after being deserialized and need updates. - DECL_UPDATE_OFFSETS = 35, + DECL_UPDATE_OFFSETS = 29, /// \brief Record of updates for a declaration that was modified after /// being deserialized. - DECL_UPDATES = 36, + DECL_UPDATES = 30, /// \brief Record code for the table of offsets to CXXBaseSpecifier /// sets. - CXX_BASE_SPECIFIER_OFFSETS = 37, + CXX_BASE_SPECIFIER_OFFSETS = 31, /// \brief Record code for \#pragma diagnostic mappings. - DIAG_PRAGMA_MAPPINGS = 38, + DIAG_PRAGMA_MAPPINGS = 32, /// \brief Record code for special CUDA declarations. - CUDA_SPECIAL_DECL_REFS = 39, + CUDA_SPECIAL_DECL_REFS = 33, /// \brief Record code for header search information. - HEADER_SEARCH_TABLE = 40, - - /// \brief The directory that the PCH was originally created in. - ORIGINAL_PCH_DIR = 41, + HEADER_SEARCH_TABLE = 34, /// \brief Record code for floating point \#pragma options. - FP_PRAGMA_OPTIONS = 42, + FP_PRAGMA_OPTIONS = 35, /// \brief Record code for enabled OpenCL extensions. - OPENCL_EXTENSIONS = 43, + OPENCL_EXTENSIONS = 36, /// \brief The list of delegating constructor declarations. - DELEGATING_CTORS = 44, + DELEGATING_CTORS = 37, - /// \brief Record code for the table of offsets into the block - /// of file source-location information. - FILE_SOURCE_LOCATION_OFFSETS = 45, - /// \brief Record code for the set of known namespaces, which are used /// for typo correction. - KNOWN_NAMESPACES = 46, + KNOWN_NAMESPACES = 38, /// \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, + MODULE_OFFSET_MAP = 39, /// \brief Record code for the source manager line table information, /// which stores information about \#line directives. - SOURCE_MANAGER_LINE_TABLE = 48, + SOURCE_MANAGER_LINE_TABLE = 40, /// \brief Record code for map of Objective-C class definition IDs to the /// ObjC categories in a module that are attached to that class. - OBJC_CATEGORIES_MAP = 49, + OBJC_CATEGORIES_MAP = 41, /// \brief Record code for a file sorted array of DeclIDs in a module. - FILE_SORTED_DECLS = 50, + FILE_SORTED_DECLS = 42, /// \brief Record code for an array of all of the (sub)modules that were /// imported by the AST file. - IMPORTED_MODULES = 51, + IMPORTED_MODULES = 43, /// \brief Record code for the set of merged declarations in an AST file. - MERGED_DECLARATIONS = 52, + MERGED_DECLARATIONS = 44, /// \brief Record code for the array of redeclaration chains. /// /// This array can only be interpreted properly using the local /// redeclarations map. - LOCAL_REDECLARATIONS = 53, + LOCAL_REDECLARATIONS = 45, /// \brief Record code for the array of Objective-C categories (including /// extensions). /// /// This array can only be interpreted properly using the Objective-C /// categories map. - OBJC_CATEGORIES = 54 + OBJC_CATEGORIES = 46, + + /// \brief Record code for the table of offsets of each macro ID. + /// + /// The offset table contains offsets into the blob stored in + /// the preprocessor block. Each offset points to the corresponding + /// macro definition. + MACRO_OFFSET = 47, + + /// \brief Record of updates for a macro that was modified after + /// being deserialized. + MACRO_UPDATES = 48 }; /// \brief Record types used within a source manager block. @@ -537,16 +580,21 @@ namespace clang { SUBMODULE_UMBRELLA_HEADER = 2, /// \brief Specifies a header that falls into this (sub)module. SUBMODULE_HEADER = 3, + /// \brief Specifies a top-level header that falls into this (sub)module. + SUBMODULE_TOPHEADER = 4, /// \brief Specifies an umbrella directory. - SUBMODULE_UMBRELLA_DIR = 4, + SUBMODULE_UMBRELLA_DIR = 5, /// \brief Specifies the submodules that are imported by this /// submodule. - SUBMODULE_IMPORTS = 5, + SUBMODULE_IMPORTS = 6, /// \brief Specifies the submodules that are re-exported from this /// submodule. - SUBMODULE_EXPORTS = 6, + SUBMODULE_EXPORTS = 7, /// \brief Specifies a required feature. - SUBMODULE_REQUIRES = 7 + SUBMODULE_REQUIRES = 8, + /// \brief Specifies a header that has been explicitly excluded + /// from this submodule. + SUBMODULE_EXCLUDED_HEADER = 9 }; /// \brief Record types used within a comments block. @@ -642,7 +690,9 @@ namespace clang { /// \brief The pseudo-object placeholder type. PREDEF_TYPE_PSEUDO_OBJECT = 35, /// \brief The __va_list_tag placeholder type. - PREDEF_TYPE_VA_LIST_TAG = 36 + PREDEF_TYPE_VA_LIST_TAG = 36, + /// \brief The placeholder type for builtin functions. + PREDEF_TYPE_BUILTIN_FN = 37 }; /// \brief The number of predefined type IDs that are reserved for @@ -943,6 +993,9 @@ namespace clang { /// \brief A NonTypeTemplateParmDecl record that stores an expanded /// non-type template parameter pack. DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK, + /// \brief A TemplateTemplateParmDecl record that stores an expanded + /// template template parameter pack. + DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK, /// \brief A ClassScopeFunctionSpecializationDecl record a class scope /// function specialization. (Microsoft extension). DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION, @@ -999,8 +1052,10 @@ namespace clang { STMT_RETURN, /// \brief A DeclStmt record. STMT_DECL, - /// \brief An AsmStmt record. - STMT_ASM, + /// \brief A GCC-style AsmStmt record. + STMT_GCCASM, + /// \brief A MS-style AsmStmt record. + STMT_MSASM, /// \brief A PredefinedExpr record. EXPR_PREDEFINED, /// \brief A DeclRefExpr record. @@ -1186,6 +1241,7 @@ namespace clang { EXPR_SIZEOF_PACK, // SizeOfPackExpr EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr + EXPR_FUNCTION_PARM_PACK, // FunctionParmPackExpr EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr // CUDA diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTDeserializationListener.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTDeserializationListener.h index ab0d313..0218129 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTDeserializationListener.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTDeserializationListener.h @@ -23,6 +23,7 @@ class Decl; class ASTReader; class QualType; class MacroDefinition; +class MacroInfo; class Module; class ASTDeserializationListener { @@ -37,6 +38,8 @@ public: /// \brief An identifier was deserialized from the AST file. virtual void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) { } + /// \brief A macro was read from the AST file. + virtual void MacroRead(serialization::MacroID ID, MacroInfo *MI) { } /// \brief A type was deserialized from the AST file. The ID here has the /// qualifier bits already removed, and T is guaranteed to be locally /// unqualified. @@ -48,9 +51,6 @@ public: /// \brief A macro definition was read from the AST file. virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinition *MD) { } - /// \brief A macro definition that had previously been deserialized - /// (and removed via IdentifierRead) has now been made visible. - virtual void MacroVisible(IdentifierInfo *II) { } /// \brief A module definition was read from the AST file. virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) { } }; diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h index f0b7275..e23ea5c 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h @@ -24,6 +24,7 @@ #include "clang/AST/TemplateBase.h" #include "clang/Lex/ExternalPreprocessorSource.h" #include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/PPMutationListener.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" @@ -33,6 +34,7 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" @@ -61,6 +63,7 @@ class ASTUnit; // FIXME: Layering violation and egregious hack. class Attr; class Decl; class DeclContext; +class DiagnosticOptions; class NestedNameSpecifier; class CXXBaseSpecifier; class CXXConstructorDecl; @@ -70,6 +73,7 @@ class MacroDefinition; class NamedDecl; class OpaqueValueExpr; class Preprocessor; +class PreprocessorOptions; class Sema; class SwitchCase; class ASTDeserializationListener; @@ -80,15 +84,7 @@ class ASTStmtReader; class TypeLocReader; struct HeaderFileInfo; class VersionTuple; - -struct PCHPredefinesBlock { - /// \brief The file ID for this predefines buffer in a PCH file. - FileID BufferID; - - /// \brief This predefines buffer in a PCH file. - StringRef Data; -}; -typedef SmallVector<PCHPredefinesBlock, 2> PCHPredefinesBlocks; +class TargetOptions; /// \brief Abstract interface for callback invocations by the ASTReader. /// @@ -103,32 +99,58 @@ public: /// \brief Receives the language options. /// /// \returns true to indicate the options are invalid or false otherwise. - virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { + virtual bool ReadLanguageOptions(const LangOptions &LangOpts, + bool Complain) { return false; } - /// \brief Receives the target triple. + /// \brief Receives the target options. /// - /// \returns true to indicate the target triple is invalid or false otherwise. - virtual bool ReadTargetTriple(StringRef Triple) { + /// \returns true to indicate the target options are invalid, or false + /// otherwise. + virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, + bool Complain) { return false; } - /// \brief Receives the contents of the predefines buffer. + /// \brief Receives the diagnostic options. /// - /// \param Buffers Information about the predefines buffers. + /// \returns true to indicate the diagnostic options are invalid, or false + /// otherwise. + virtual bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts, + bool Complain) { + return false; + } + + /// \brief Receives the file system options. /// - /// \param OriginalFileName The original file name for the AST file, which - /// will appear as an entry in the predefines buffer. + /// \returns true to indicate the file system options are invalid, or false + /// otherwise. + virtual bool ReadFileSystemOptions(const FileSystemOptions &FSOpts, + bool Complain) { + return false; + } + + /// \brief Receives the header search options. + /// + /// \returns true to indicate the header search options are invalid, or false + /// otherwise. + virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + bool Complain) { + return false; + } + + /// \brief Receives the preprocessor options. /// - /// \param SuggestedPredefines If necessary, additional definitions are added - /// here. + /// \param SuggestedPredefines Can be filled in with the set of predefines + /// that are suggested by the preprocessor options. Typically only used when + /// loading a precompiled header. /// - /// \returns true to indicate the predefines are invalid or false otherwise. - virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, - StringRef OriginalFileName, - std::string &SuggestedPredefines, - FileManager &FileMgr) { + /// \returns true to indicate the preprocessor options are invalid, or false + /// otherwise. + virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool Complain, + std::string &SuggestedPredefines) { return false; } @@ -136,7 +158,8 @@ public: virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) {} /// \brief Receives __COUNTER__ value. - virtual void ReadCounter(unsigned Value) {} + virtual void ReadCounter(const serialization::ModuleFile &M, + unsigned Value) {} }; /// \brief ASTReaderListener implementation to validate the information of @@ -151,14 +174,15 @@ public: PCHValidator(Preprocessor &PP, ASTReader &Reader) : PP(PP), Reader(Reader), NumHeaderInfos(0) {} - virtual bool ReadLanguageOptions(const LangOptions &LangOpts); - virtual bool ReadTargetTriple(StringRef Triple); - virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, - StringRef OriginalFileName, - std::string &SuggestedPredefines, - FileManager &FileMgr); + virtual bool ReadLanguageOptions(const LangOptions &LangOpts, + bool Complain); + virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, + bool Complain); + virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool Complain, + std::string &SuggestedPredefines); virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID); - virtual void ReadCounter(unsigned Value); + virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value); private: void Error(const char *Msg); @@ -201,7 +225,26 @@ class ASTReader public: typedef SmallVector<uint64_t, 64> RecordData; - enum ASTReadResult { Success, Failure, IgnorePCH }; + /// \brief The result of reading the control block of an AST file, which + /// can fail for various reasons. + enum ASTReadResult { + /// \brief The control block was read successfully. Aside from failures, + /// the AST file is safe to read into the current context. + Success, + /// \brief The AST file itself appears corrupted. + Failure, + /// \brief The AST file is out-of-date relative to its input files, + /// and needs to be regenerated. + OutOfDate, + /// \brief The AST file was written by a different version of Clang. + VersionMismatch, + /// \brief The AST file was writtten with a different language/target + /// configuration. + ConfigurationMismatch, + /// \brief The AST file has errors. + HadErrors + }; + /// \brief Types of AST files. friend class PCHValidator; friend class ASTDeclReader; @@ -341,7 +384,15 @@ private: /// \brief The set of C++ or Objective-C classes that have forward /// declarations that have not yet been linked to their definitions. llvm::SmallPtrSet<Decl *, 4> PendingDefinitions; - + + typedef llvm::MapVector<Decl *, uint64_t, + llvm::SmallDenseMap<Decl *, unsigned, 4>, + llvm::SmallVector<std::pair<Decl *, uint64_t>, 4> > + PendingBodiesMap; + + /// \brief Functions or methods that have bodies that will be attached. + PendingBodiesMap PendingBodies; + /// \brief Read the records that describe the contents of declcontexts. bool ReadDeclContextStorage(ModuleFile &M, llvm::BitstreamCursor &Cursor, @@ -359,11 +410,36 @@ private: typedef ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4> GlobalIdentifierMapType; - /// \brief Mapping from global identifer IDs to the module in which the + /// \brief Mapping from global identifier 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 macros that have already been + /// loaded. + /// + /// If the pointer at index I is non-NULL, then it refers to the + /// MacroInfo for the identifier with ID=I+1 that has already + /// been loaded. + std::vector<MacroInfo *> MacrosLoaded; + + typedef ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4> + GlobalMacroMapType; + + /// \brief Mapping from global macro IDs to the module in which the + /// macro resides along with the offset that should be added to the + /// global macro ID to produce a local ID. + GlobalMacroMapType GlobalMacroMap; + + typedef llvm::DenseMap<serialization::MacroID, + llvm::SmallVector<std::pair<serialization::SubmoduleID, + MacroUpdate>, 1> > + MacroUpdatesMap; + + /// \brief Mapping from (global) macro IDs to the set of updates to be + /// performed to the corresponding macro. + MacroUpdatesMap MacroUpdates; + /// \brief A vector containing submodules that have already been loaded. /// /// This vector is indexed by the Submodule ID (-1). NULL submodule entries @@ -378,8 +454,55 @@ private: /// global submodule ID to produce a local ID. GlobalSubmoduleMapType GlobalSubmoduleMap; + /// \brief An entity that has been hidden. + class HiddenName { + public: + enum NameKind { + Declaration, + MacroVisibility, + MacroUndef + } Kind; + + private: + unsigned Loc; + + union { + Decl *D; + MacroInfo *MI; + }; + + IdentifierInfo *Id; + + public: + HiddenName(Decl *D) : Kind(Declaration), Loc(), D(D), Id() { } + + HiddenName(IdentifierInfo *II, MacroInfo *MI) + : Kind(MacroVisibility), Loc(), MI(MI), Id(II) { } + + HiddenName(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc) + : Kind(MacroUndef), Loc(Loc.getRawEncoding()), MI(MI), Id(II) { } + + NameKind getKind() const { return Kind; } + + Decl *getDecl() const { + assert(getKind() == Declaration && "Hidden name is not a declaration"); + return D; + } + + std::pair<IdentifierInfo *, MacroInfo *> getMacro() const { + assert((getKind() == MacroUndef || getKind() == MacroVisibility) + && "Hidden name is not a macro!"); + return std::make_pair(Id, MI); + } + + SourceLocation getMacroUndefLoc() const { + assert(getKind() == MacroUndef && "Hidden name is not an undef!"); + return SourceLocation::getFromRawEncoding(Loc); + } +}; + /// \brief A set of hidden declarations. - typedef llvm::SmallVector<llvm::PointerUnion<Decl *, IdentifierInfo *>, 2> + typedef llvm::SmallVector<HiddenName, 2> HiddenNames; typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType; @@ -431,10 +554,13 @@ private: /// global method pool for this selector. llvm::DenseMap<Selector, unsigned> SelectorGeneration; - /// \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 llvm::MapVector<IdentifierInfo *, + llvm::SmallVector<serialization::MacroID, 2> > + PendingMacroIDsMap; + + /// \brief Mapping from identifiers that have a macro history to the global + /// IDs have not yet been deserialized to the global IDs of those macros. + PendingMacroIDsMap PendingMacroIDs; typedef ContinuousRangeMap<unsigned, ModuleFile *, 4> GlobalPreprocessedEntityMapType; @@ -553,28 +679,9 @@ private: SmallVector<serialization::SubmoduleID, 2> ImportedModules; //@} - /// \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; - - /// \brief The actual original file name that was used to build the primary - /// AST file. - std::string ActualOriginalFileName; - - /// \brief The file ID for the original file that was used to build the - /// primary AST file. - FileID OriginalFileID; - - /// \brief The directory that the PCH was originally created in. Used to - /// allow resolving headers even after headers+PCH was moved to a new path. - std::string OriginalDir; - /// \brief The directory that the PCH we are reading is stored in. std::string CurrentDir; - /// \brief Whether this precompiled header is a relocatable PCH file. - bool RelocatablePCH; - /// \brief The system include root to be used when loading the /// precompiled header. std::string isysroot; @@ -583,9 +690,6 @@ private: /// headers when they are loaded. bool DisableValidation; - /// \brief Whether to disable the use of stat caches in AST files. - bool DisableStatCache; - /// \brief Whether to accept an AST file with compiler errors. bool AllowASTWithCompilerErrors; @@ -602,10 +706,6 @@ private: SwitchCaseMapTy *CurrSwitchCaseStmts; - /// \brief The number of stat() calls that hit/missed the stat - /// cache. - unsigned NumStatHits, NumStatMisses; - /// \brief The number of source location entries de-serialized from /// the PCH file. unsigned NumSLocEntriesRead; @@ -687,7 +787,7 @@ private: /// Objective-C protocols. std::deque<Decl *> InterestingDecls; - /// \brief The set of redeclarable declaraations that have been deserialized + /// \brief The set of redeclarable declarations that have been deserialized /// since the last time the declaration chains were linked. llvm::SmallPtrSet<Decl *, 16> RedeclsDeserialized; @@ -758,8 +858,8 @@ private: ASTReader &Reader; enum ReadingKind PrevKind; - ReadingKindTracker(const ReadingKindTracker&); // do not implement - ReadingKindTracker &operator=(const ReadingKindTracker&);// do not implement + ReadingKindTracker(const ReadingKindTracker &) LLVM_DELETED_FUNCTION; + void operator=(const ReadingKindTracker &) LLVM_DELETED_FUNCTION; public: ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader) @@ -770,10 +870,6 @@ private: ~ReadingKindTracker() { Reader.ReadingKind = PrevKind; } }; - /// \brief All predefines buffers in the chain, to be treated as if - /// concatenated. - PCHPredefinesBlocks PCHPredefinesBuffers; - /// \brief Suggested contents of the predefines buffer, after this /// PCH file has been processed. /// @@ -787,24 +883,45 @@ private: /// \brief Reads a statement from the specified cursor. Stmt *ReadStmtFromStream(ModuleFile &F); + typedef llvm::PointerIntPair<const FileEntry *, 1, bool> InputFile; + + /// \brief Retrieve the file entry and 'overridden' bit for an input + /// file in the given module file. + InputFile getInputFile(ModuleFile &F, unsigned ID, bool Complain = true); + /// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take /// into account all the necessary relocations. const FileEntry *getFileEntry(StringRef filename); - void MaybeAddSystemRootToFilename(std::string &Filename); + void MaybeAddSystemRootToFilename(ModuleFile &M, std::string &Filename); ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, - ModuleFile *ImportedBy); - ASTReadResult ReadASTBlock(ModuleFile &F); - bool CheckPredefinesBuffers(); + ModuleFile *ImportedBy, + llvm::SmallVectorImpl<ModuleFile *> &Loaded, + unsigned ClientLoadCapabilities); + ASTReadResult ReadControlBlock(ModuleFile &F, + llvm::SmallVectorImpl<ModuleFile *> &Loaded, + unsigned ClientLoadCapabilities); + bool ReadASTBlock(ModuleFile &F); bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record); - ASTReadResult ReadSourceManagerBlock(ModuleFile &F); - ASTReadResult ReadSLocEntryRecord(int ID); + bool ReadSourceManagerBlock(ModuleFile &F); llvm::BitstreamCursor &SLocCursorForID(int ID); SourceLocation getImportLocation(ModuleFile *F); - ASTReadResult ReadSubmoduleBlock(ModuleFile &F); - bool ParseLanguageOptions(const RecordData &Record); - + bool ReadSubmoduleBlock(ModuleFile &F); + static bool ParseLanguageOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseTargetOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseFileSystemOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParsePreprocessorOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener, + std::string &SuggestedPredefines); + struct RecordLocation { RecordLocation(ModuleFile *M, uint64_t O) : F(M), Offset(O) {} @@ -836,18 +953,82 @@ private: /// \brief Find the next module that contains entities and return the ID /// of the first entry. - /// \arg SLocMapI points at a chunk of a module that contains no + /// + /// \param 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. serialization::PreprocessedEntityID findNextPreprocessedEntity( GlobalSLocOffsetMapType::const_iterator SLocMapI) const; - /// \brief Returns (ModuleFile, Local index) pair for \arg GlobalIndex of a + /// \brief Returns (ModuleFile, Local index) pair for \p GlobalIndex of a /// preprocessed entity. std::pair<ModuleFile *, unsigned> getModulePreprocessedEntity(unsigned GlobalIndex); + /// \brief Returns (begin, end) pair for the preprocessed entities of a + /// particular module. + std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> + getModulePreprocessedEntities(ModuleFile &Mod) const; + + class ModuleDeclIterator { + ASTReader *Reader; + ModuleFile *Mod; + const serialization::LocalDeclID *Pos; + + public: + typedef const Decl *value_type; + typedef value_type& reference; + typedef value_type* pointer; + + ModuleDeclIterator() : Reader(0), Mod(0), Pos(0) { } + + ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, + const serialization::LocalDeclID *Pos) + : Reader(Reader), Mod(Mod), Pos(Pos) { } + + value_type operator*() const { + return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *Pos)); + } + + ModuleDeclIterator &operator++() { + ++Pos; + return *this; + } + + ModuleDeclIterator operator++(int) { + ModuleDeclIterator Prev(*this); + ++Pos; + return Prev; + } + + ModuleDeclIterator &operator--() { + --Pos; + return *this; + } + + ModuleDeclIterator operator--(int) { + ModuleDeclIterator Prev(*this); + --Pos; + return Prev; + } + + friend bool operator==(const ModuleDeclIterator &LHS, + const ModuleDeclIterator &RHS) { + assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod); + return LHS.Pos == RHS.Pos; + } + + friend bool operator!=(const ModuleDeclIterator &LHS, + const ModuleDeclIterator &RHS) { + assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod); + return LHS.Pos != RHS.Pos; + } + }; + + std::pair<ModuleDeclIterator, ModuleDeclIterator> + getModuleFileLevelDecls(ModuleFile &Mod); + void PassInterestingDeclsToConsumer(); void PassInterestingDeclToConsumer(Decl *D); @@ -861,8 +1042,8 @@ private: void Error(unsigned DiagID, StringRef Arg1 = StringRef(), StringRef Arg2 = StringRef()); - ASTReader(const ASTReader&); // do not implement - ASTReader &operator=(const ASTReader &); // do not implement + ASTReader(const ASTReader &) LLVM_DELETED_FUNCTION; + void operator=(const ASTReader &) LLVM_DELETED_FUNCTION; public: /// \brief Load the AST file and validate its contents against the given /// Preprocessor. @@ -881,29 +1062,49 @@ public: /// 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. - /// /// \param AllowASTWithCompilerErrors If true, the AST reader will accept an /// AST file the was created out of an AST with compiler errors, /// otherwise it will reject it. ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "", - bool DisableValidation = false, bool DisableStatCache = false, + bool DisableValidation = false, bool AllowASTWithCompilerErrors = false); ~ASTReader(); 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 Flags that indicate what kind of AST loading failures the client + /// of the AST reader can directly handle. + /// + /// When a client states that it can handle a particular kind of failure, + /// the AST reader will not emit errors when producing that kind of failure. + enum LoadFailureCapabilities { + /// \brief The client can't handle any AST loading failures. + ARR_None = 0, + /// \brief The client can handle an AST file that cannot load because it + /// is out-of-date relative to its input files. + ARR_OutOfDate = 0x1, + /// \brief The client can handle an AST file that cannot load because it + /// was built with a different version of Clang. + ARR_VersionMismatch = 0x2, + /// \brief The client can handle an AST file that cannot load because it's + /// compiled configuration doesn't match that of the context it was + /// loaded into. + ARR_ConfigurationMismatch = 0x4 + }; - /// \brief Checks that no file that is stored in PCH is out-of-sync with - /// the actual file in the file system. - ASTReadResult validateFileEntries(ModuleFile &M); + /// \brief Load the AST file designated by the given file name. + /// + /// \param FileName The name of the AST file to load. + /// + /// \param Type The kind of AST being loaded, e.g., PCH, module, main file, + /// or preamble. + /// + /// \param ClientLoadCapabilities The set of client load-failure + /// capabilities, represented as a bitset of the enumerators of + /// LoadFailureCapabilities. + ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type, + unsigned ClientLoadCapabilities); /// \brief Make the entities in the given module and any of its (non-explicit) /// submodules visible to name lookup. @@ -947,8 +1148,11 @@ public: /// \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; } + /// \brief Retrieve the name of the original source file name for the primary + /// module file. + StringRef getOriginalSourceFile() { + return ModuleMgr.getPrimaryModule().OriginalSourceFileName; + } /// \brief Retrieve the name of the original source file name directly from /// the AST file, without actually loading the AST file. @@ -956,6 +1160,21 @@ public: FileManager &FileMgr, DiagnosticsEngine &Diags); + /// \brief Read the control block for the named AST file. + /// + /// \returns true if an error occurred, false otherwise. + static bool readASTFileControlBlock(StringRef Filename, + FileManager &FileMgr, + ASTReaderListener &Listener); + + /// \brief Determine whether the given AST file is acceptable to load into a + /// translation unit with the given language and target options. + static bool isAcceptableASTFile(StringRef Filename, + FileManager &FileMgr, + const LangOptions &LangOpts, + const TargetOptions &TargetOpts, + const PreprocessorOptions &PPOpts); + /// \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. @@ -968,12 +1187,12 @@ public: virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index); /// \brief Returns a pair of [Begin, End) indices of preallocated - /// preprocessed entities that \arg Range encompasses. + /// preprocessed entities that \p Range encompasses. virtual std::pair<unsigned, unsigned> findPreprocessedEntitiesInRange(SourceRange Range); /// \brief Optionally returns true or false if the preallocated preprocessed - /// entity with index \arg Index came from file \arg FID. + /// entity with index \p Index came from file \p FID. virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index, FileID FID); @@ -992,6 +1211,11 @@ public: return static_cast<unsigned>(IdentifiersLoaded.size()); } + /// \brief Returns the number of macros found in the chain. + unsigned getTotalNumMacros() const { + return static_cast<unsigned>(MacrosLoaded.size()); + } + /// \brief Returns the number of types found in the chain. unsigned getTotalNumTypes() const { return static_cast<unsigned>(TypesLoaded.size()); @@ -1065,17 +1289,17 @@ public: /// \brief Map from a local declaration ID within a given module to a /// global declaration ID. - serialization::DeclID getGlobalDeclID(ModuleFile &F, unsigned LocalID) const; + serialization::DeclID getGlobalDeclID(ModuleFile &F, + serialization::LocalDeclID LocalID) const; - /// \brief Returns true if global DeclID \arg ID originated from module - /// \arg M. + /// \brief Returns true if global DeclID \p ID originated from module \p M. bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const; /// \brief Retrieve the module file that owns the given declaration, or NULL /// if the declaration is not from a module file. ModuleFile *getOwningModuleFile(Decl *D); - /// \brief Returns the source location for the decl \arg ID. + /// \brief Returns the source location for the decl \p ID. SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID); /// \brief Resolve a declaration ID into a declaration, potentially @@ -1172,7 +1396,7 @@ public: SmallVectorImpl<Decl*> &Decls); /// \brief Get the decls that are contained in a file in the Offset/Length - /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of + /// range. \p Length can be 0 to indicate a point at \p Offset instead of /// a range. virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length, SmallVectorImpl<Decl *> &Decls); @@ -1285,6 +1509,9 @@ public: } virtual IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) { + // Note that we are loading an identifier. + Deserializing AnIdentifier(this); + return DecodeIdentifierInfo(ID); } @@ -1293,6 +1520,13 @@ public: serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M, unsigned LocalID); + /// \brief Retrieve the macro with the given ID. + MacroInfo *getMacro(serialization::MacroID ID, MacroInfo *Hint = 0); + + /// \brief Retrieve the global macro ID corresponding to the given local + /// ID within the given module file. + serialization::MacroID getGlobalMacroID(ModuleFile &M, unsigned LocalID); + /// \brief Read the source location entry with index ID. virtual bool ReadSLocEntry(int ID); @@ -1404,10 +1638,10 @@ public: llvm::APFloat ReadAPFloat(const RecordData &Record, unsigned &Idx); // \brief Read a string - std::string ReadString(const RecordData &Record, unsigned &Idx); + static std::string ReadString(const RecordData &Record, unsigned &Idx); /// \brief Read a version tuple. - VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx); + static VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx); CXXTemporary *ReadCXXTemporary(ModuleFile &F, const RecordData &Record, unsigned &Idx); @@ -1436,43 +1670,29 @@ public: Expr *ReadSubExpr(); /// \brief Reads the macro record located at the given offset. - void ReadMacroRecord(ModuleFile &F, uint64_t Offset); + void ReadMacroRecord(ModuleFile &F, uint64_t Offset, MacroInfo *Hint = 0); /// \brief Determine the global preprocessed entity ID that corresponds to /// the given local ID within the given module. serialization::PreprocessedEntityID getGlobalPreprocessedEntityID(ModuleFile &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. + /// \brief Note that the identifier has a macro history. /// /// \param II The name of the macro. /// - /// \param F The module file from which the macro definition was deserialized. - /// - /// \param Offset The offset into the module file at which the macro - /// definition is located. - /// - /// \param Visible Whether the macro should be made visible. - void setIdentifierIsMacro(IdentifierInfo *II, ModuleFile &F, - uint64_t Offset, bool Visible); + /// \param IDs The global macro IDs that are associated with this identifier. + void setIdentifierIsMacro(IdentifierInfo *II, + ArrayRef<serialization::MacroID> IDs); /// \brief Read the set of macros defined by this external macro source. virtual void ReadDefinedMacros(); - /// \brief Read the macro definition for this identifier. - virtual void LoadMacroDefinition(IdentifierInfo *II); - /// \brief Update an out-of-date identifier. virtual void updateOutOfDateIdentifier(IdentifierInfo &II); /// \brief Note that this identifier is up-to-date. void markIdentifierUpToDate(IdentifierInfo *II); - - /// \brief Read the macro definition corresponding to this iterator - /// into the unread macro record offsets table. - void LoadMacroDefinition( - llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos); /// \brief Load all external visible decls in the given DeclContext. void completeVisibleDeclsMap(const DeclContext *DC); diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h index d038d58..ac81e21 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h @@ -18,6 +18,7 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/ASTMutationListener.h" +#include "clang/Lex/PPMutationListener.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Sema/SemaConsumer.h" @@ -25,6 +26,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SetVector.h" #include "llvm/Bitcode/BitstreamWriter.h" #include <map> @@ -43,14 +45,15 @@ class ASTContext; class NestedNameSpecifier; class CXXBaseSpecifier; class CXXCtorInitializer; +class FileEntry; class FPOptions; class HeaderSearch; class IdentifierResolver; class MacroDefinition; -class MemorizeStatCalls; class OpaqueValueExpr; class OpenCLOptions; class ASTReader; +class MacroInfo; class Module; class PreprocessedEntity; class PreprocessingRecord; @@ -70,6 +73,7 @@ namespace SrcMgr { class SLocEntry; } /// data structures. This bitstream can be de-serialized via an /// instance of the ASTReader class. class ASTWriter : public ASTDeserializationListener, + public PPMutationListener, public ASTMutationListener { public: typedef SmallVector<uint64_t, 64> RecordData; @@ -117,6 +121,10 @@ private: /// \brief Indicates that the AST contained compiler errors. bool ASTHasCompilerErrors; + /// \brief Mapping from input file entries to the index into the + /// offset table where information about that input file is stored. + llvm::DenseMap<const FileEntry *, uint32_t> InputFileIDs; + /// \brief Stores a declaration or a type to be written to the AST file. class DeclOrType { public: @@ -171,8 +179,7 @@ private: /// indicates the index that this particular vector has in the global one. unsigned FirstDeclIndex; }; - typedef llvm::DenseMap<const SrcMgr::SLocEntry *, - DeclIDInFileInfo *> FileDeclIDsTy; + typedef llvm::DenseMap<FileID, DeclIDInFileInfo *> FileDeclIDsTy; /// \brief Map from file SLocEntries to info about the file-level declarations /// that it contains. @@ -215,6 +222,15 @@ private: /// IdentifierInfo. llvm::DenseMap<const IdentifierInfo *, serialization::IdentID> IdentifierIDs; + /// \brief The first ID number we can use for our own macros. + serialization::MacroID FirstMacroID; + + /// \brief The identifier ID that will be assigned to the next new identifier. + serialization::MacroID NextMacroID; + + /// \brief Map that provides the ID numbers of each macro. + llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs; + /// @name FlushStmt Caches /// @{ @@ -250,16 +266,10 @@ private: /// table, indexed by the Selector ID (-1). std::vector<uint32_t> SelectorOffsets; - /// \brief Offsets of each of the macro identifiers into the - /// bitstream. - /// - /// For each identifier that is associated with a macro, this map - /// provides the offset into the bitstream where that macro is - /// defined. - llvm::DenseMap<const IdentifierInfo *, uint64_t> MacroOffsets; + typedef llvm::MapVector<MacroInfo *, MacroUpdate> MacroUpdatesMap; - /// \brief The set of identifiers that had macro definitions at some point. - std::vector<const IdentifierInfo *> DeserializedMacroNames; + /// \brief Updates to macro definitions that were loaded from an AST file. + MacroUpdatesMap MacroUpdates; /// \brief Mapping from macro definitions (as they occur in the preprocessing /// record) to the macro IDs. @@ -403,10 +413,9 @@ private: llvm::DenseSet<Stmt *> &ParentStmts); void WriteBlockInfoBlock(); - void WriteMetadata(ASTContext &Context, StringRef isysroot, - const std::string &OutputFile); - void WriteLanguageOptions(const LangOptions &LangOpts); - void WriteStatCache(MemorizeStatCalls &StatCalls); + void WriteControlBlock(Preprocessor &PP, ASTContext &Context, + StringRef isysroot, const std::string &OutputFile); + void WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot); void WriteSourceManagerBlock(SourceManager &SourceMgr, const Preprocessor &PP, StringRef isysroot); @@ -428,6 +437,7 @@ private: void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver, bool IsModule); void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record); + void WriteMacroUpdates(); void ResolveDeclUpdatesBlocks(); void WriteDeclUpdatesBlocks(); void WriteDeclReplacementsBlock(); @@ -455,7 +465,7 @@ private: void WriteDeclsBlockAbbrevs(); void WriteDecl(ASTContext &Context, Decl *D); - void WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, + void WriteASTCore(Sema &SemaRef, StringRef isysroot, const std::string &OutputFile, Module *WritingModule); @@ -470,15 +480,12 @@ public: /// \param SemaRef a reference to the semantic analysis object that processed /// the AST to be written into the precompiled header. /// - /// \param StatCalls the object that cached all of the stat() calls made while - /// searching for source files and headers. - /// /// \param WritingModule The module that we are writing. If null, we are /// writing a precompiled header. /// /// \param isysroot if non-empty, write a relocatable file whose headers /// are relative to the given system root. - void WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, + void WriteAST(Sema &SemaRef, const std::string &OutputFile, Module *WritingModule, StringRef isysroot, bool hasErrors = false); @@ -501,6 +508,9 @@ public: /// \brief Emit a reference to an identifier. void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record); + /// \brief Emit a reference to a macro. + void addMacroRef(MacroInfo *MI, RecordDataImpl &Record); + /// \brief Emit a Selector (which is a smart pointer reference). void AddSelectorRef(Selector, RecordDataImpl &Record); @@ -518,15 +528,8 @@ public: /// \brief Get the unique number used to refer to the given identifier. serialization::IdentID getIdentifierRef(const IdentifierInfo *II); - /// \brief Retrieve the offset of the macro definition for the given - /// identifier. - /// - /// The identifier must refer to a macro. - uint64_t getMacroOffset(const IdentifierInfo *II) { - assert(MacroOffsets.find(II) != MacroOffsets.end() && - "Identifier does not name a macro"); - return MacroOffsets[II]; - } + /// \brief Get the unique number used to refer to the given macro. + serialization::MacroID getMacroRef(MacroInfo *MI); /// \brief Emit a reference to a type. void AddTypeRef(QualType T, RecordDataImpl &Record); @@ -689,13 +692,16 @@ public: // ASTDeserializationListener implementation void ReaderInitialized(ASTReader *Reader); void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II); + void MacroRead(serialization::MacroID ID, MacroInfo *MI); void TypeRead(serialization::TypeIdx Idx, QualType T); void SelectorRead(serialization::SelectorID ID, Selector Sel); void MacroDefinitionRead(serialization::PreprocessedEntityID ID, MacroDefinition *MD); - void MacroVisible(IdentifierInfo *II); void ModuleRead(serialization::SubmoduleID ID, Module *Mod); - + + // PPMutationListener implementation. + virtual void UndefinedMacro(MacroInfo *MI); + // ASTMutationListener implementation. virtual void CompletedTagDefinition(const TagDecl *D); virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D); @@ -722,7 +728,6 @@ class PCHGenerator : public SemaConsumer { std::string isysroot; raw_ostream *Out; Sema *SemaPtr; - MemorizeStatCalls *StatCalls; // owned by the FileManager llvm::SmallVector<char, 128> Buffer; llvm::BitstreamWriter Stream; ASTWriter Writer; @@ -738,6 +743,7 @@ public: ~PCHGenerator(); virtual void InitializeSema(Sema &S) { SemaPtr = &S; } virtual void HandleTranslationUnit(ASTContext &Ctx); + virtual PPMutationListener *GetPPMutationListener(); virtual ASTMutationListener *GetASTMutationListener(); virtual ASTDeserializationListener *GetASTDeserializationListener(); }; diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ContinuousRangeMap.h b/contrib/llvm/tools/clang/include/clang/Serialization/ContinuousRangeMap.h index f368a80..d89cd02 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ContinuousRangeMap.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ContinuousRangeMap.h @@ -108,8 +108,8 @@ public: class Builder { ContinuousRangeMap &Self; - Builder(const Builder&); // DO NOT IMPLEMENT - Builder &operator=(const Builder&); // DO NOT IMPLEMENT + Builder(const Builder&) LLVM_DELETED_FUNCTION; + Builder &operator=(const Builder&) LLVM_DELETED_FUNCTION; public: explicit Builder(ContinuousRangeMap &Self) : Self(Self) { } diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/Module.h b/contrib/llvm/tools/clang/include/clang/Serialization/Module.h index 786ecd3..39fa3d9 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/Module.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/Module.h @@ -25,6 +25,7 @@ namespace clang { +class FileEntry; class DeclContext; class Module; template<typename Info> class OnDiskChainedHashTable; @@ -74,6 +75,29 @@ public: /// \brief The file name of the module file. std::string FileName; + /// \brief The original source file name that was used to build the + /// primary AST file, which may have been modified for + /// relocatable-pch support. + std::string OriginalSourceFileName; + + /// \brief The actual original source file name that was used to + /// build this AST file. + std::string ActualOriginalSourceFileName; + + /// \brief The file ID for the original source file that was used to + /// build this AST file. + FileID OriginalSourceFileID; + + /// \brief The directory that the PCH was originally created in. Used to + /// allow resolving headers even after headers+PCH was moved to a new path. + std::string OriginalDir; + + /// \brief Whether this precompiled header is a relocatable PCH file. + bool RelocatablePCH; + + /// \brief The file entry for the module file. + const FileEntry *File; + /// \brief Whether this module has been directly imported by the /// user. bool DirectlyImported; @@ -98,11 +122,24 @@ public: llvm::BitstreamCursor Stream; /// \brief The source location where this module was first imported. + /// FIXME: This is not properly initialized yet. SourceLocation ImportLoc; /// \brief The first source location in this module. SourceLocation FirstLoc; + // === Input Files === + /// \brief The cursor to the start of the input-files block. + llvm::BitstreamCursor InputFilesCursor; + + /// \brief Offsets for all of the input file entries in the AST file. + const uint32_t *InputFileOffsets; + + /// \brief The input files that have been loaded from this AST file, along + /// with a bool indicating whether this was an overridden buffer. + std::vector<llvm::PointerIntPair<const FileEntry *, 1, bool> > + InputFilesLoaded; + // === Source Locations === /// \brief Cursor used to read source location entries. @@ -124,13 +161,6 @@ public: /// \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; @@ -168,6 +198,22 @@ public: /// all of the macro definitions. llvm::BitstreamCursor MacroCursor; + /// \brief The number of macros in this AST file. + unsigned LocalNumMacros; + + /// \brief Offsets of macros in the preprocessor block. + /// + /// This array is indexed by the macro ID (-1), and provides + /// the offset into the preprocessor block where macro definitions are + /// stored. + const uint32_t *MacroOffsets; + + /// \brief Base macro ID for macros local to this module. + serialization::MacroID BaseMacroID; + + /// \brief Remapping table for macro IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> MacroRemap; + /// \brief The offset of the start of the set of defined macros. uint64_t MacroStartOffset; @@ -294,6 +340,7 @@ public: /// \brief Array of file-level DeclIDs sorted by file. const serialization::DeclID *FileSortedDecls; + unsigned NumFileSortedDecls; /// \brief Array of redeclaration chain location information within this /// module file, sorted by the first declaration ID. @@ -338,11 +385,6 @@ public: /// \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<ModuleFile *> ImportedBy; diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h index 6ff0640..6dcaa21 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h @@ -34,7 +34,7 @@ class ModuleManager { /// \brief FileManager that handles translating between filenames and /// FileEntry *. - FileManager FileMgr; + FileManager &FileMgr; /// \brief A lookup of in-memory (virtual file) buffers llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers; @@ -45,7 +45,7 @@ public: typedef SmallVector<ModuleFile*, 2>::reverse_iterator ModuleReverseIterator; typedef std::pair<uint32_t, StringRef> ModuleOffset; - ModuleManager(const FileSystemOptions &FSO); + explicit ModuleManager(FileManager &FileMgr); ~ModuleManager(); /// \brief Forward iterator to traverse all loaded modules. This is reverse @@ -105,7 +105,10 @@ public: std::pair<ModuleFile *, bool> addModule(StringRef FileName, ModuleKind Type, ModuleFile *ImportedBy, unsigned Generation, std::string &ErrorStr); - + + /// \brief Remove the given set of modules. + void removeModules(ModuleIterator first, ModuleIterator last); + /// \brief Add an in-memory buffer the list of known buffers void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer); diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/DereferenceChecker.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/DereferenceChecker.h deleted file mode 100644 index f9cce9c..0000000 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/DereferenceChecker.h +++ /dev/null @@ -1,35 +0,0 @@ -//== NullDerefChecker.h - Null dereference checker --------------*- C++ -*--==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This defines NullDerefChecker and UndefDerefChecker, two builtin checks -// in ExprEngine that check for null and undefined pointers at loads -// and stores. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_GR_DEREFCHECKER -#define LLVM_CLANG_GR_DEREFCHECKER - -#include <utility> - -namespace clang { - -namespace ento { - -class ExprEngine; -class ExplodedNode; - -std::pair<ExplodedNode * const *, ExplodedNode * const *> -GetImplicitNullDereferences(ExprEngine &Eng); - -} // end GR namespace - -} // end clang namespace - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Analyses.def index 29ddc9e..01a6ffd 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/Analyses.def +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Analyses.def @@ -21,7 +21,6 @@ ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateR #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) #endif -ANALYSIS_CONSTRAINTS(BasicConstraints, "basic", "Use basic constraint tracking", CreateBasicConstraintManager) ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager) #ifndef ANALYSIS_DIAGNOSTICS @@ -47,6 +46,7 @@ ANALYSIS_PURGE(PurgeNone, "none", "Do not purge symbols, bindings, or constrain #endif ANALYSIS_IPA(None, "none", "Perform only intra-procedural analysis") +ANALYSIS_IPA(BasicInlining, "basic-inlining", "Inline C functions and blocks when their definitions are available") ANALYSIS_IPA(Inlining, "inlining", "Inline callees when their definitions are available") ANALYSIS_IPA(DynamicDispatch, "dynamic", "Experimental: Enable inlining of dynamically dispatched methods") ANALYSIS_IPA(DynamicDispatchBifurcate, "dynamic-bifurcate", "Experimental: Enable inlining of dynamically dispatched methods, bifurcate paths when exact type info is unavailable") diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h new file mode 100644 index 0000000..fa0754a --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -0,0 +1,308 @@ +//===--- AnalyzerOptions.h - Analysis Engine Options ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header defines various options for the static analyzer that are set +// by the frontend and are consulted throughout the analyzer. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYZEROPTIONS_H +#define LLVM_CLANG_ANALYZEROPTIONS_H + +#include <string> +#include <vector> +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringMap.h" + +namespace clang { +class ASTConsumer; +class DiagnosticsEngine; +class Preprocessor; +class LangOptions; + +/// Analysis - Set of available source code analyses. +enum Analyses { +#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME, +#include "clang/StaticAnalyzer/Core/Analyses.def" +NumAnalyses +}; + +/// AnalysisStores - Set of available analysis store models. +enum AnalysisStores { +#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model, +#include "clang/StaticAnalyzer/Core/Analyses.def" +NumStores +}; + +/// AnalysisConstraints - Set of available constraint models. +enum AnalysisConstraints { +#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model, +#include "clang/StaticAnalyzer/Core/Analyses.def" +NumConstraints +}; + +/// AnalysisDiagClients - Set of available diagnostic clients for rendering +/// analysis results. +enum AnalysisDiagClients { +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) PD_##NAME, +#include "clang/StaticAnalyzer/Core/Analyses.def" +NUM_ANALYSIS_DIAG_CLIENTS +}; + +/// AnalysisPurgeModes - Set of available strategies for dead symbol removal. +enum AnalysisPurgeMode { +#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME, +#include "clang/StaticAnalyzer/Core/Analyses.def" +NumPurgeModes +}; + +/// AnalysisIPAMode - Set of inter-procedural modes. +enum AnalysisIPAMode { +#define ANALYSIS_IPA(NAME, CMDFLAG, DESC) NAME, +#include "clang/StaticAnalyzer/Core/Analyses.def" +NumIPAModes +}; + +/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics. +enum AnalysisInliningMode { +#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME, +#include "clang/StaticAnalyzer/Core/Analyses.def" +NumInliningModes +}; + +/// \brief Describes the different kinds of C++ member functions which can be +/// considered for inlining by the analyzer. +/// +/// These options are cumulative; enabling one kind of member function will +/// enable all kinds with lower enum values. +enum CXXInlineableMemberKind { + // Uninitialized = 0, + + /// A dummy mode in which no C++ inlining is enabled. + CIMK_None = 1, + + /// Refers to regular member function and operator calls. + CIMK_MemberFunctions, + + /// Refers to constructors (implicit or explicit). + /// + /// Note that a constructor will not be inlined if the corresponding + /// destructor is non-trivial. + CIMK_Constructors, + + /// Refers to destructors (implicit or explicit). + CIMK_Destructors +}; + + +class AnalyzerOptions : public llvm::RefCountedBase<AnalyzerOptions> { +public: + typedef llvm::StringMap<std::string> ConfigTable; + + /// \brief Pair of checker name and enable/disable. + std::vector<std::pair<std::string, bool> > CheckersControlList; + + /// \brief A key-value table of use-specified configuration values. + ConfigTable Config; + AnalysisStores AnalysisStoreOpt; + AnalysisConstraints AnalysisConstraintsOpt; + AnalysisDiagClients AnalysisDiagOpt; + AnalysisPurgeMode AnalysisPurgeOpt; + + // \brief The interprocedural analysis mode. + AnalysisIPAMode IPAMode; + + std::string AnalyzeSpecificFunction; + + /// \brief The maximum number of exploded nodes the analyzer will generate. + unsigned MaxNodes; + + /// \brief The maximum number of times the analyzer visits a block. + unsigned maxBlockVisitOnPath; + + + unsigned ShowCheckerHelp : 1; + unsigned AnalyzeAll : 1; + unsigned AnalyzerDisplayProgress : 1; + unsigned AnalyzeNestedBlocks : 1; + + /// \brief The flag regulates if we should eagerly assume evaluations of + /// conditionals, thus, bifurcating the path. + /// + /// This flag indicates how the engine should handle expressions such as: 'x = + /// (y != 0)'. When this flag is true then the subexpression 'y != 0' will be + /// eagerly assumed to be true or false, thus evaluating it to the integers 0 + /// or 1 respectively. The upside is that this can increase analysis + /// precision until we have a better way to lazily evaluate such logic. The + /// downside is that it eagerly bifurcates paths. + unsigned eagerlyAssumeBinOpBifurcation : 1; + + unsigned TrimGraph : 1; + unsigned visualizeExplodedGraphWithGraphViz : 1; + unsigned visualizeExplodedGraphWithUbiGraph : 1; + unsigned UnoptimizedCFG : 1; + unsigned PrintStats : 1; + + /// \brief Do not re-analyze paths leading to exhausted nodes with a different + /// strategy. We get better code coverage when retry is enabled. + unsigned NoRetryExhausted : 1; + + /// \brief The inlining stack depth limit. + unsigned InlineMaxStackDepth; + + /// \brief The mode of function selection used during inlining. + unsigned InlineMaxFunctionSize; + + /// \brief The mode of function selection used during inlining. + AnalysisInliningMode InliningMode; + +private: + /// Controls which C++ member functions will be considered for inlining. + CXXInlineableMemberKind CXXMemberInliningMode; + + /// \sa includeTemporaryDtorsInCFG + llvm::Optional<bool> IncludeTemporaryDtorsInCFG; + + /// \sa mayInlineCXXStandardLibrary + llvm::Optional<bool> InlineCXXStandardLibrary; + + /// \sa mayInlineTemplateFunctions + llvm::Optional<bool> InlineTemplateFunctions; + + /// \sa mayInlineObjCMethod + llvm::Optional<bool> ObjCInliningMode; + + // Cache of the "ipa-always-inline-size" setting. + // \sa getAlwaysInlineSize + llvm::Optional<unsigned> AlwaysInlineSize; + + /// \sa shouldPruneNullReturnPaths + llvm::Optional<bool> PruneNullReturnPaths; + + /// \sa shouldAvoidSuppressingNullArgumentPaths + llvm::Optional<bool> AvoidSuppressingNullArgumentPaths; + + /// \sa getGraphTrimInterval + llvm::Optional<unsigned> GraphTrimInterval; + + /// Interprets an option's string value as a boolean. + /// + /// Accepts the strings "true" and "false". + /// If an option value is not provided, returns the given \p DefaultVal. + bool getBooleanOption(StringRef Name, bool DefaultVal); + + /// Variant that accepts a Optional value to cache the result. + bool getBooleanOption(llvm::Optional<bool> &V, StringRef Name, + bool DefaultVal); + + /// Interprets an option's string value as an integer value. + int getOptionAsInteger(llvm::StringRef Name, int DefaultVal); + +public: + /// Returns the option controlling which C++ member functions will be + /// considered for inlining. + /// + /// This is controlled by the 'c++-inlining' config option. + /// + /// \sa CXXMemberInliningMode + bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K); + + /// Returns true if ObjectiveC inlining is enabled, false otherwise. + bool mayInlineObjCMethod(); + + /// Returns whether or not the destructors for C++ temporary objects should + /// be included in the CFG. + /// + /// This is controlled by the 'cfg-temporary-dtors' config option, which + /// accepts the values "true" and "false". + bool includeTemporaryDtorsInCFG(); + + /// Returns whether or not C++ standard library functions may be considered + /// for inlining. + /// + /// This is controlled by the 'c++-stdlib-inlining' config option, which + /// accepts the values "true" and "false". + bool mayInlineCXXStandardLibrary(); + + /// Returns whether or not templated functions may be considered for inlining. + /// + /// This is controlled by the 'c++-template-inlining' config option, which + /// accepts the values "true" and "false". + bool mayInlineTemplateFunctions(); + + /// Returns whether or not paths that go through null returns should be + /// suppressed. + /// + /// This is a heuristic for avoiding bug reports with paths that go through + /// inlined functions that are more defensive than their callers. + /// + /// This is controlled by the 'suppress-null-return-paths' config option, + /// which accepts the values "true" and "false". + bool shouldPruneNullReturnPaths(); + + /// Returns whether a bug report should \em not be suppressed if its path + /// includes a call with a null argument, even if that call has a null return. + /// + /// This option has no effect when #shouldPruneNullReturnPaths() is false. + /// + /// This is a counter-heuristic to avoid false negatives. + /// + /// This is controlled by the 'avoid-suppressing-null-argument-paths' config + /// option, which accepts the values "true" and "false". + bool shouldAvoidSuppressingNullArgumentPaths(); + + // Returns the size of the functions (in basic blocks), which should be + // considered to be small enough to always inline. + // + // This is controlled by "ipa-always-inline-size" analyzer-config option. + unsigned getAlwaysInlineSize(); + + /// Returns true if the analyzer engine should synthesize fake bodies + /// for well-known functions. + bool shouldSynthesizeBodies(); + + /// Returns how often nodes in the ExplodedGraph should be recycled to save + /// memory. + /// + /// This is controlled by the 'graph-trim-interval' config option. To disable + /// node reclamation, set the option to "0". + unsigned getGraphTrimInterval(); + +public: + AnalyzerOptions() : CXXMemberInliningMode() { + AnalysisStoreOpt = RegionStoreModel; + AnalysisConstraintsOpt = RangeConstraintsModel; + AnalysisDiagOpt = PD_HTML; + AnalysisPurgeOpt = PurgeStmt; + IPAMode = DynamicDispatchBifurcate; + ShowCheckerHelp = 0; + AnalyzeAll = 0; + AnalyzerDisplayProgress = 0; + AnalyzeNestedBlocks = 0; + eagerlyAssumeBinOpBifurcation = 0; + TrimGraph = 0; + visualizeExplodedGraphWithGraphViz = 0; + visualizeExplodedGraphWithUbiGraph = 0; + UnoptimizedCFG = 0; + PrintStats = 0; + NoRetryExhausted = 0; + // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls). + InlineMaxStackDepth = 5; + InlineMaxFunctionSize = 200; + InliningMode = NoRedundancy; + } +}; + +typedef llvm::IntrusiveRefCntPtr<AnalyzerOptions> AnalyzerOptionsRef; + +} + +#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 48393a3..b5a88ba 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 @@ -24,6 +24,7 @@ #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ImmutableSet.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallSet.h" namespace clang { @@ -95,6 +96,10 @@ protected: /// for multiple PathDiagnosticConsumers. llvm::SmallVector<Regions *, 2> interestingRegions; + /// A set of location contexts that correspoind to call sites which should be + /// considered "interesting". + llvm::SmallSet<const LocationContext *, 2> InterestingLocationContexts; + /// A set of custom visitors which generate "event" diagnostics at /// interesting points in the path. VisitorList Callbacks; @@ -111,6 +116,19 @@ protected: /// when reporting an issue. bool DoNotPrunePath; + /// Used to track unique reasons why a bug report might be invalid. + /// + /// \sa markInvalid + /// \sa removeInvalidation + typedef std::pair<const void *, const void *> InvalidationRecord; + + /// If non-empty, this bug report is likely a false positive and should not be + /// shown to the user. + /// + /// \sa markInvalid + /// \sa removeInvalidation + llvm::SmallSet<InvalidationRecord, 4> Invalidations; + private: // Used internally by BugReporter. Symbols &getInterestingSymbols(); @@ -147,7 +165,8 @@ public: PathDiagnosticLocation LocationToUnique) : BT(bt), DeclWithIssue(0), Description(desc), UniqueingLocation(LocationToUnique), - ErrorNode(errornode), ConfigurationChangeToken(0) {} + ErrorNode(errornode), ConfigurationChangeToken(0), + DoNotPrunePath(false) {} virtual ~BugReport(); @@ -158,8 +177,10 @@ public: const StringRef getDescription() const { return Description; } - const StringRef getShortDescription() const { - return ShortDescription.empty() ? Description : ShortDescription; + const StringRef getShortDescription(bool UseFallback = true) const { + if (ShortDescription.empty() && UseFallback) + return Description; + return ShortDescription; } /// Indicates whether or not any path pruning should take place @@ -172,14 +193,44 @@ public: void markInteresting(SymbolRef sym); void markInteresting(const MemRegion *R); void markInteresting(SVal V); + void markInteresting(const LocationContext *LC); bool isInteresting(SymbolRef sym); bool isInteresting(const MemRegion *R); bool isInteresting(SVal V); + bool isInteresting(const LocationContext *LC); unsigned getConfigurationChangeToken() const { return ConfigurationChangeToken; } + + /// Returns whether or not this report should be considered valid. + /// + /// Invalid reports are those that have been classified as likely false + /// positives after the fact. + bool isValid() const { + return Invalidations.empty(); + } + + /// Marks the current report as invalid, meaning that it is probably a false + /// positive and should not be reported to the user. + /// + /// The \p Tag and \p Data arguments are intended to be opaque identifiers for + /// this particular invalidation, where \p Tag represents the visitor + /// responsible for invalidation, and \p Data represents the reason this + /// visitor decided to invalidate the bug report. + /// + /// \sa removeInvalidation + void markInvalid(const void *Tag, const void *Data) { + Invalidations.insert(std::make_pair(Tag, Data)); + } + + /// Reverses the effects of a previous invalidation. + /// + /// \sa markInvalid + void removeInvalidation(const void *Tag, const void *Data) { + Invalidations.erase(std::make_pair(Tag, Data)); + } /// Return the canonical declaration, be it a method or class, where /// this issue semantically occurred. @@ -342,6 +393,11 @@ private: /// A vector of BugReports for tracking the allocated pointers and cleanup. std::vector<BugReportEquivClass *> EQClassesVector; + /// A map from PathDiagnosticPiece to the LocationContext of the inlined + /// function call it represents. + llvm::DenseMap<const PathDiagnosticCallPiece*, + const LocationContext*> LocationContextMap; + protected: BugReporter(BugReporterData& d, Kind k) : BugTypes(F.getEmptySet()), kind(k), D(d) {} @@ -378,9 +434,14 @@ public: SourceManager& getSourceManager() { return D.getSourceManager(); } - virtual void GeneratePathDiagnostic(PathDiagnostic& pathDiagnostic, + virtual bool generatePathDiagnostic(PathDiagnostic& pathDiagnostic, PathDiagnosticConsumer &PC, - ArrayRef<BugReport *> &bugReports) {} + ArrayRef<BugReport *> &bugReports) { + return true; + } + + bool RemoveUneededCalls(PathPieces &pieces, BugReport *R, + PathDiagnosticCallPiece *CallWithLoc = 0); void Register(BugType *BT); @@ -389,7 +450,7 @@ public: /// 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 emitReport(BugReport *R); void EmitBasicReport(const Decl *DeclWithIssue, StringRef BugName, StringRef BugCategory, @@ -409,8 +470,10 @@ public: EmitBasicReport(DeclWithIssue, BugName, Category, BugStr, Loc, &R, 1); } - static bool classof(const BugReporter* R) { return true; } - + void addCallPieceLocationContextPair(const PathDiagnosticCallPiece *C, + const LocationContext *LC) { + LocationContextMap[C] = LC; + } private: llvm::StringMap<BugType *> StrBugTypes; @@ -440,7 +503,15 @@ public: /// engine. ProgramStateManager &getStateManager(); - virtual void GeneratePathDiagnostic(PathDiagnostic &pathDiagnostic, + /// Generates a path corresponding to one of the given bug reports. + /// + /// Which report is used for path generation is not specified. The + /// bug reporter will try to pick the shortest path, but this is not + /// guaranteed. + /// + /// \return True if the report was valid and a path was generated, + /// false if the reports should be considered invalid. + virtual bool generatePathDiagnostic(PathDiagnostic &PD, PathDiagnosticConsumer &PC, ArrayRef<BugReport*> &bugReports); 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 index f53c15f..78e35ca 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h @@ -100,7 +100,6 @@ class FindLastStoreBRVisitor const MemRegion *R; SVal V; bool satisfied; - const ExplodedNode *StoreSite; public: /// \brief Convenience method to create a visitor given only the MemRegion. @@ -114,7 +113,7 @@ public: static void registerStatementVarDecls(BugReport &BR, const Stmt *S); FindLastStoreBRVisitor(SVal v, const MemRegion *r) - : R(r), V(v), satisfied(false), StoreSite(0) { + : R(r), V(v), satisfied(false) { assert (!V.isUnknown() && "Cannot track unknown value."); // TODO: Does it make sense to allow undef values here? @@ -142,6 +141,10 @@ public: void Profile(llvm::FoldingSetNodeID &ID) const; + /// Return the tag associated with this visitor. This tag will be used + /// to make all PathDiagnosticPieces created by this visitor. + static const char *getTag(); + PathDiagnosticPiece *VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, @@ -171,6 +174,9 @@ public: ID.AddPointer(&x); } + /// Return the tag associated with this visitor. This tag will be used + /// to make all PathDiagnosticPieces created by this visitor. + static const char *getTag(); virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N, const ExplodedNode *Prev, @@ -223,15 +229,57 @@ public: const ExplodedNode *N, llvm::Optional<bool> &prunable); }; - + +/// \brief When a region containing undefined value or '0' value is passed +/// as an argument in a call, marks the call as interesting. +/// +/// As a result, BugReporter will not prune the path through the function even +/// if the region's contents are not modified/accessed by the call. +class UndefOrNullArgVisitor + : public BugReporterVisitorImpl<UndefOrNullArgVisitor> { + + /// The interesting memory region this visitor is tracking. + const MemRegion *R; + +public: + UndefOrNullArgVisitor(const MemRegion *InR) : R(InR) {} + + virtual void Profile(llvm::FoldingSetNodeID &ID) const { + static int Tag = 0; + ID.AddPointer(&Tag); + ID.AddPointer(R); + } + + PathDiagnosticPiece *VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR); +}; + namespace bugreporter { -void addTrackNullOrUndefValueVisitor(const ExplodedNode *N, const Stmt *S, - BugReport *R); +/// Attempts to add visitors to trace a null or undefined value back to its +/// point of origin, whether it is a symbol constrained to null or an explicit +/// assignment. +/// +/// \param N A node "downstream" from the evaluation of the statement. +/// \param S The statement whose value is null or undefined. +/// \param R The bug report to which visitors should be attached. +/// \param IsArg Whether the statement is an argument to an inlined function. +/// If this is the case, \p N \em must be the CallEnter node for +/// the function. +/// +/// \return Whether or not the function was able to add visitors for this +/// statement. Note that returning \c true does not actually imply +/// that any visitors were added. +bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R, + bool IsArg = false); const Stmt *GetDerefExpr(const ExplodedNode *N); const Stmt *GetDenomExpr(const ExplodedNode *N); const Stmt *GetRetValExpr(const ExplodedNode *N); +bool isDeclRefExprToReference(const Expr *E); + } // end namespace clang } // end namespace ento 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 973cfb1..6dc26e6 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 @@ -52,7 +52,31 @@ class PathDiagnostic; class PathDiagnosticConsumer { public: - typedef std::vector<std::pair<StringRef, std::string> > FilesMade; + class PDFileEntry : public llvm::FoldingSetNode { + public: + PDFileEntry(llvm::FoldingSetNodeID &NodeID) : NodeID(NodeID) {} + + typedef std::vector<std::pair<StringRef, StringRef> > ConsumerFiles; + + /// \brief A vector of <consumer,file> pairs. + ConsumerFiles files; + + /// \brief A precomputed hash tag used for uniquing PDFileEntry objects. + const llvm::FoldingSetNodeID NodeID; + + /// \brief Used for profiling in the FoldingSet. + void Profile(llvm::FoldingSetNodeID &ID) { ID = NodeID; } + }; + + struct FilesMade : public llvm::FoldingSet<PDFileEntry> { + llvm::BumpPtrAllocator Alloc; + + void addDiagnostic(const PathDiagnostic &PD, + StringRef ConsumerName, + StringRef fileName); + + PDFileEntry::ConsumerFiles *getFiles(const PathDiagnostic &PD); + }; private: virtual void anchor(); @@ -73,7 +97,6 @@ public: virtual PathGenerationScheme getGenerationScheme() const { return Minimal; } virtual bool supportsLogicalOpControlFlow() const { return false; } virtual bool supportsAllBlockEdges() const { return false; } - virtual bool useVerboseDescription() const { return true; } /// Return true if the PathDiagnosticConsumer supports individual /// PathDiagnostics that span multiple files. @@ -114,8 +137,6 @@ private: Kind kind) : K(kind), S(0), D(0), SM(&sm), Loc(genLocation(L)), Range(genRange()) { - assert(Loc.isValid()); - assert(Range.isValid()); } FullSourceLoc @@ -134,12 +155,14 @@ public: PathDiagnosticLocation(const Stmt *s, const SourceManager &sm, LocationOrAnalysisDeclContext lac) - : K(StmtK), S(s), D(0), SM(&sm), + : K(s->getLocStart().isValid() ? StmtK : SingleLocK), + S(K == StmtK ? s : 0), + D(0), SM(&sm), Loc(genLocation(SourceLocation(), lac)), Range(genRange(lac)) { - assert(S); - assert(Loc.isValid()); - assert(Range.isValid()); + assert(K == SingleLocK || S); + assert(K == SingleLocK || Loc.isValid()); + assert(K == SingleLocK || Range.isValid()); } /// Create a location corresponding to the given declaration. @@ -297,12 +320,18 @@ private: const std::string str; const Kind kind; const DisplayHint Hint; + + /// A constant string that can be used to tag the PathDiagnosticPiece, + /// typically with the identification of the creator. The actual pointer + /// value is meant to be an identifier; the string itself is useful for + /// debugging. + StringRef Tag; + std::vector<SourceRange> ranges; - // Do not implement: - PathDiagnosticPiece(); - PathDiagnosticPiece(const PathDiagnosticPiece &P); - PathDiagnosticPiece& operator=(const PathDiagnosticPiece &P); + PathDiagnosticPiece() LLVM_DELETED_FUNCTION; + PathDiagnosticPiece(const PathDiagnosticPiece &P) LLVM_DELETED_FUNCTION; + void operator=(const PathDiagnosticPiece &P) LLVM_DELETED_FUNCTION; protected: PathDiagnosticPiece(StringRef s, Kind k, DisplayHint hint = Below); @@ -312,8 +341,18 @@ protected: public: virtual ~PathDiagnosticPiece(); - const std::string& getString() const { return str; } + llvm::StringRef getString() const { return str; } + /// Tag this PathDiagnosticPiece with the given C-string. + void setTag(const char *tag) { Tag = tag; } + + /// Return the opaque tag (if any) on the PathDiagnosticPiece. + const void *getTag() const { return Tag.data(); } + + /// Return the string representation of the tag. This is useful + /// for debugging. + StringRef getTagStr() const { return Tag; } + /// getDisplayHint - Return a hint indicating where the diagnostic should /// be displayed by the PathDiagnosticConsumer. DisplayHint getDisplayHint() const { return Hint; } @@ -338,10 +377,6 @@ public: /// Return the SourceRanges associated with this PathDiagnosticPiece. ArrayRef<SourceRange> getRanges() const { return ranges; } - static inline bool classof(const PathDiagnosticPiece *P) { - return true; - } - virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; @@ -377,6 +412,10 @@ public: virtual void flattenLocations() { Pos.flatten(); } virtual void Profile(llvm::FoldingSetNodeID &ID) const; + + static bool classof(const PathDiagnosticPiece *P) { + return P->getKind() == Event || P->getKind() == Macro; + } }; /// \brief Interface for classes constructing Stack hints. @@ -410,10 +449,6 @@ public: /// 'getMessageForX()' methods to construct a specific message. virtual std::string getMessage(const ExplodedNode *N); - /// Prints the ordinal form of the given integer, - /// only valid for ValNo : ValNo > 0. - void printOrdinal(unsigned ValNo, llvm::raw_svector_ostream &Out); - /// Produces the message of the following form: /// 'Msg via Nth parameter' virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex); @@ -629,14 +664,22 @@ public: class PathDiagnostic : public llvm::FoldingSetNode { const Decl *DeclWithIssue; std::string BugType; - std::string Desc; + std::string VerboseDesc; + std::string ShortDesc; std::string Category; std::deque<std::string> OtherDesc; + PathDiagnosticLocation Loc; PathPieces pathImpl; llvm::SmallVector<PathPieces *, 3> pathStack; PathDiagnostic(); // Do not implement. public: + PathDiagnostic(const Decl *DeclWithIssue, StringRef bugtype, + StringRef verboseDesc, StringRef shortDesc, + StringRef category); + + ~PathDiagnostic(); + const PathPieces &path; /// Return the path currently used by builders for constructing the @@ -659,16 +702,24 @@ public: void popActivePath() { if (!pathStack.empty()) pathStack.pop_back(); } bool isWithinCall() const { return !pathStack.empty(); } - - // PathDiagnostic(); - PathDiagnostic(const Decl *DeclWithIssue, - StringRef bugtype, - StringRef desc, - StringRef category); - ~PathDiagnostic(); + void setEndOfPath(PathDiagnosticPiece *EndPiece) { + assert(!Loc.isValid() && "End location already set!"); + Loc = EndPiece->getLocation(); + assert(Loc.isValid() && "Invalid location for end-of-path piece"); + getActivePath().push_back(EndPiece); + } - StringRef getDescription() const { return Desc; } + void resetPath() { + pathStack.clear(); + pathImpl.clear(); + Loc = PathDiagnosticLocation(); + } + + StringRef getVerboseDescription() const { return VerboseDesc; } + StringRef getShortDescription() const { + return ShortDesc.empty() ? VerboseDesc : ShortDesc; + } StringRef getBugType() const { return BugType; } StringRef getCategory() const { return Category; } @@ -682,15 +733,27 @@ public: meta_iterator meta_end() const { return OtherDesc.end(); } void addMeta(StringRef s) { OtherDesc.push_back(s); } - PathDiagnosticLocation getLocation() const; + PathDiagnosticLocation getLocation() const { + assert(Loc.isValid() && "No end-of-path location set yet!"); + return Loc; + } void flattenLocations() { + Loc.flatten(); for (PathPieces::iterator I = pathImpl.begin(), E = pathImpl.end(); I != E; ++I) (*I)->flattenLocations(); } - + + /// Profiles the diagnostic, independent of the path it references. + /// + /// This can be used to merge diagnostics that refer to the same issue + /// along different paths. void Profile(llvm::FoldingSetNodeID &ID) const; - + + /// Profiles the diagnostic, including its path. + /// + /// Two diagnostics with the same issue along different paths will generate + /// different profiles. void FullProfile(llvm::FoldingSetNodeID &ID) const; }; 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 3214d96..9eb1248 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -366,23 +366,6 @@ 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 { 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 e11b6d5..7ae8e53 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -258,7 +258,7 @@ public: const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, ExprEngine &Eng, - ProgramPoint::Kind PointKind); + const ProgramPoint &PP); /// \brief Run checkers for end of analysis. void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, @@ -267,6 +267,7 @@ public: /// \brief Run checkers for end of path. void runCheckersForEndPath(NodeBuilderContext &BC, ExplodedNodeSet &Dst, + ExplodedNode *Pred, ExprEngine &Eng); /// \brief Run checkers for branch condition. @@ -407,11 +408,6 @@ public: 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; @@ -449,8 +445,6 @@ public: void _registerForEvalCall(EvalCallFunc checkfn); - void _registerForInlineCall(InlineCallFunc checkfn); - void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn); //===----------------------------------------------------------------------===// @@ -576,8 +570,6 @@ private: std::vector<EvalCallFunc> EvalCallCheckers; - std::vector<InlineCallFunc> InlineCallCheckers; - std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers; struct EventInfo { diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h index e1ff17b..27f3677 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h @@ -66,6 +66,10 @@ public: return llvm::APSInt::getMaxValue(BitWidth, IsUnsigned); } + llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY { + return (llvm::APSInt(BitWidth, IsUnsigned) = RawValue); + } + /// Used to classify whether a value is representable using this type. /// /// \see testInRange 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 876196b..9038ae5 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,7 +16,7 @@ #define LLVM_CLANG_GR_ANALYSISMANAGER_H #include "clang/Analysis/AnalysisContext.h" -#include "clang/Frontend/AnalyzerOptions.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h" @@ -41,64 +41,16 @@ class AnalysisManager : public BugReporterData { CheckerManager *CheckerMgr; - /// \brief The maximum number of exploded nodes the analyzer will generate. - unsigned MaxNodes; - - /// \brief The maximum number of times the analyzer visits a block. - unsigned MaxVisit; - - bool VisualizeEGDot; - bool VisualizeEGUbi; - AnalysisPurgeMode PurgeDead; - - /// \brief The flag regulates if we should eagerly assume evaluations of - /// conditionals, thus, bifurcating the path. - /// - /// EagerlyAssume - A flag indicating how the engine should handle - /// expressions such as: 'x = (y != 0)'. When this flag is true then - /// the subexpression 'y != 0' will be eagerly assumed to be true or false, - /// thus evaluating it to the integers 0 or 1 respectively. The upside - /// is that this can increase analysis precision until we have a better way - /// to lazily evaluate such logic. The downside is that it eagerly - /// bifurcates paths. - bool EagerlyAssume; - bool TrimGraph; - bool EagerlyTrimEGraph; - -public: - // \brief inter-procedural analysis mode. - AnalysisIPAMode IPAMode; - - // Settings for inlining tuning. - /// \brief The inlining stack depth limit. - unsigned InlineMaxStackDepth; - /// \brief The max number of basic blocks in a function being inlined. - unsigned InlineMaxFunctionSize; - /// \brief The mode of function selection used during inlining. - AnalysisInliningMode InliningMode; - - /// \brief Do not re-analyze paths leading to exhausted nodes with a different - /// strategy. We get better code coverage when retry is enabled. - bool NoRetryExhausted; - public: + AnalyzerOptions &options; + AnalysisManager(ASTContext &ctx,DiagnosticsEngine &diags, const LangOptions &lang, const PathDiagnosticConsumers &Consumers, StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr, - unsigned maxnodes, unsigned maxvisit, - bool vizdot, bool vizubi, AnalysisPurgeMode purge, - bool eager, bool trim, - bool useUnoptimizedCFG, - bool addImplicitDtors, - bool eagerlyTrimEGraph, - AnalysisIPAMode ipa, - unsigned inlineMaxStack, - unsigned inlineMaxFunctionSize, - AnalysisInliningMode inliningMode, - bool NoRetry); + AnalyzerOptions &Options); ~AnalysisManager(); @@ -142,27 +94,14 @@ public: void FlushDiagnostics(); - unsigned getMaxNodes() const { return MaxNodes; } - - unsigned getMaxVisit() const { return MaxVisit; } - - bool shouldVisualizeGraphviz() const { return VisualizeEGDot; } - - bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; } - bool shouldVisualize() const { - return VisualizeEGDot || VisualizeEGUbi; + return options.visualizeExplodedGraphWithGraphViz || + options.visualizeExplodedGraphWithUbiGraph; } - bool shouldEagerlyTrimExplodedGraph() const { return EagerlyTrimEGraph; } - - bool shouldTrimGraph() const { return TrimGraph; } - - AnalysisPurgeMode getPurgeMode() const { return PurgeDead; } - - bool shouldEagerlyAssume() const { return EagerlyAssume; } - - bool shouldInlineCall() const { return (IPAMode != None); } + bool shouldInlineCall() const { + return options.IPAMode != None; + } CFG *getCFG(Decl const *D) { return AnaCtxMgr.getContext(D)->getCFG(); @@ -180,7 +119,6 @@ public: AnalysisDeclContext *getAnalysisDeclContext(const Decl *D) { return AnaCtxMgr.getContext(D); } - }; } // enAnaCtxMgrspace 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 b4a9de7..fb39354 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 @@ -73,6 +73,10 @@ class BasicValueFactory { llvm::FoldingSet<CompoundValData> CompoundValDataSet; llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet; + // This is private because external clients should use the factory + // method that takes a QualType. + const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned); + public: BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator& Alloc) : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0), @@ -84,7 +88,6 @@ public: const llvm::APSInt& getValue(const llvm::APSInt& X); const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned); - const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned); const llvm::APSInt& getValue(uint64_t X, QualType T); /// Returns the type of the APSInt used to store values of the given QualType. diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index f6c5830..a6a91e2 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -20,6 +20,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/Analysis/AnalysisContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "llvm/ADT/PointerIntPair.h" @@ -68,15 +69,22 @@ public: } }; +/// \class RuntimeDefinition /// \brief Defines the runtime definition of the called function. +/// +/// Encapsulates the information we have about which Decl will be used +/// when the call is executed on the given path. When dealing with dynamic +/// dispatch, the information is based on DynamicTypeInfo and might not be +/// precise. class RuntimeDefinition { - /// The Declaration of the function which will be called at runtime. - /// 0 if not available. + /// The Declaration of the function which could be called at runtime. + /// NULL if not available. const Decl *D; /// The region representing an object (ObjC/C++) on which the method is /// called. With dynamic dispatch, the method definition depends on the - /// runtime type of this object. 0 when there is no dynamic dispatch. + /// runtime type of this object. NULL when the DynamicTypeInfo is + /// precise. const MemRegion *R; public: @@ -84,8 +92,15 @@ public: RuntimeDefinition(const Decl *InD): D(InD), R(0) {} RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {} const Decl *getDecl() { return D; } - const MemRegion *getDispatchRegion() { return R; } + + /// \brief Check if the definition we have is precise. + /// If not, it is possible that the call dispatches to another definition at + /// execution time. bool mayHaveOtherDefinitions() { return R != 0; } + + /// When other definitions are possible, returns the region whose runtime type + /// determines the method definition. + const MemRegion *getDispatchRegion() { return R; } }; /// \brief Represents an abstract call to a function or method along a @@ -106,8 +121,7 @@ private: const LocationContext *LCtx; llvm::PointerUnion<const Expr *, const Decl *> Origin; - // DO NOT IMPLEMENT - CallEvent &operator=(const CallEvent &); + void operator=(const CallEvent &) LLVM_DELETED_FUNCTION; protected: // This is user data for subclasses. @@ -139,16 +153,6 @@ protected: : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin), Data(Original.Data), Location(Original.Location), RefCount(0) {} - - ProgramStateRef getState() const { - return State; - } - - const LocationContext *getLocationContext() const { - return LCtx; - } - - /// Copies this CallEvent, with vtable intact, into a new block of memory. virtual void cloneTo(void *Dest) const = 0; @@ -164,8 +168,6 @@ protected: /// result of this call. virtual void getExtraInvalidatedRegions(RegionList &Regions) const {} - virtual QualType getDeclaredResultType() const = 0; - public: virtual ~CallEvent() {} @@ -178,6 +180,16 @@ public: return Origin.dyn_cast<const Decl *>(); } + /// \brief The state in which the call is being evaluated. + ProgramStateRef getState() const { + return State; + } + + /// \brief The context in which the call is being evaluated. + const LocationContext *getLocationContext() const { + return LCtx; + } + /// \brief Returns the definition of the function or method that will be /// called. virtual RuntimeDefinition getRuntimeDefinition() const = 0; @@ -237,6 +249,12 @@ public: /// \brief Returns the result type, adjusted for references. QualType getResultType() const; + /// \brief Returns the return value of the call. + /// + /// This should only be called if the CallEvent was created using a state in + /// which the return value has already been bound to the origin expression. + SVal getReturnValue() const; + /// \brief Returns true if any of the arguments appear to represent callbacks. bool hasNonZeroCallbackArg() const; @@ -249,6 +267,38 @@ public: return hasNonZeroCallbackArg(); } + /// \brief Returns true if the callee is an externally-visible function in the + /// top-level namespace, such as \c malloc. + /// + /// You can use this call to determine that a particular function really is + /// a library function and not, say, a C++ member function with the same name. + /// + /// If a name is provided, the function must additionally match the given + /// name. + /// + /// Note that this deliberately excludes C++ library functions in the \c std + /// namespace, but will include C library functions accessed through the + /// \c std namespace. This also does not check if the function is declared + /// as 'extern "C"', or if it uses C++ name mangling. + // FIXME: Add a helper for checking namespaces. + // FIXME: Move this down to AnyFunctionCall once checkers have more + // precise callbacks. + bool isGlobalCFunction(StringRef SpecificName = StringRef()) const; + + /// \brief Returns the name of the callee, if its name is a simple identifier. + /// + /// Note that this will fail for Objective-C methods, blocks, and C++ + /// overloaded operators. The former is named by a Selector rather than a + /// simple identifier, and the latter two do not have names. + // FIXME: Move this down to AnyFunctionCall once checkers have more + // precise callbacks. + const IdentifierInfo *getCalleeIdentifier() const { + const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getDecl()); + if (!ND) + return 0; + return ND->getIdentifier(); + } + /// \brief Returns an appropriate ProgramPoint for this call. ProgramPoint getProgramPoint(bool IsPreVisit = false, const ProgramPointTag *Tag = 0) const; @@ -277,12 +327,12 @@ public: return cloneWithState<CallEvent>(NewState); } - /// \brief Returns true if this is a statement that can be considered for - /// inlining. - /// - /// FIXME: This should go away once CallEvents are cheap and easy to - /// construct from ExplodedNodes. - static bool mayBeInlined(const Stmt *S); + /// \brief Returns true if this is a statement is a function or method call + /// of some kind. + static bool isCallStmt(const Stmt *S); + + /// \brief Returns the result type of a function, method declaration. + static QualType getDeclaredResultType(const Decl *D); // Iterator access to formal parameters and their types. private: @@ -329,8 +379,6 @@ public: // For debugging purposes only void dump(raw_ostream &Out) const; LLVM_ATTRIBUTE_USED void dump() const; - - static bool classof(const CallEvent *) { return true; } }; @@ -346,8 +394,6 @@ protected: : CallEvent(D, St, LCtx) {} AnyFunctionCall(const AnyFunctionCall &Other) : CallEvent(Other) {} - virtual QualType getDeclaredResultType() const; - public: // This function is overridden by subclasses, but they must return // a FunctionDecl. @@ -357,9 +403,16 @@ public: virtual RuntimeDefinition getRuntimeDefinition() const { const FunctionDecl *FD = getDecl(); - // Note that hasBody() will fill FD with the definition FunctionDecl. - if (FD && FD->hasBody(FD)) - return RuntimeDefinition(FD); + // Note that the AnalysisDeclContext will have the FunctionDecl with + // the definition (if one exists). + if (FD) { + AnalysisDeclContext *AD = + getLocationContext()->getAnalysisDeclContext()-> + getManager()->getContext(FD); + if (AD->getBody()) + return RuntimeDefinition(AD->getDecl()); + } + return RuntimeDefinition(); } @@ -442,8 +495,6 @@ protected: virtual void getExtraInvalidatedRegions(RegionList &Regions) const; - virtual QualType getDeclaredResultType() const; - public: /// \brief Returns the region associated with this instance of the block. /// @@ -499,13 +550,7 @@ public: virtual const Expr *getCXXThisExpr() const { return 0; } /// \brief Returns the value of the implicit 'this' object. - virtual SVal getCXXThisVal() const { - const Expr *Base = getCXXThisExpr(); - // FIXME: This doesn't handle an overloaded ->* operator. - if (!Base) - return UnknownVal(); - return getSVal(Base); - } + virtual SVal getCXXThisVal() const; virtual const FunctionDecl *getDecl() const; @@ -550,6 +595,8 @@ public: } virtual const Expr *getCXXThisExpr() const; + + virtual RuntimeDefinition getRuntimeDefinition() const; virtual Kind getKind() const { return CE_CXXMember; } @@ -605,6 +652,8 @@ class CXXDestructorCall : public CXXInstanceCall { friend class CallEventManager; protected: + typedef llvm::PointerIntPair<const MemRegion *, 1, bool> DtorDataTy; + /// Creates an implicit destructor. /// /// \param DD The destructor that will be called. @@ -613,10 +662,10 @@ protected: /// \param St The path-sensitive state at this point in the program. /// \param LCtx The location context at this point in the program. CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, - const MemRegion *Target, ProgramStateRef St, - const LocationContext *LCtx) + const MemRegion *Target, bool IsBaseDestructor, + ProgramStateRef St, const LocationContext *LCtx) : CXXInstanceCall(DD, St, LCtx) { - Data = Target; + Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue(); Location = Trigger->getLocEnd(); } @@ -627,9 +676,16 @@ public: virtual SourceRange getSourceRange() const { return Location; } virtual unsigned getNumArgs() const { return 0; } + virtual RuntimeDefinition getRuntimeDefinition() const; + /// \brief Returns the value of the implicit 'this' object. virtual SVal getCXXThisVal() const; + /// Returns true if this is a call to a base class destructor. + bool isBaseDestructor() const { + return DtorDataTy::getFromOpaqueValue(Data).getInt(); + } + virtual Kind getKind() const { return CE_CXXDestructor; } static bool classof(const CallEvent *CA) { @@ -651,10 +707,10 @@ protected: /// a new symbolic region will be used. /// \param St The path-sensitive state at this point in the program. /// \param LCtx The location context at this point in the program. - CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *target, + CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *Target, ProgramStateRef St, const LocationContext *LCtx) : AnyFunctionCall(CE, St, LCtx) { - Data = target; + Data = Target; } CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){} @@ -761,8 +817,6 @@ protected: virtual void getExtraInvalidatedRegions(RegionList &Regions) const; - virtual QualType getDeclaredResultType() const; - /// Check if the selector may have multiple definitions (may have overrides). virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, Selector Sel) const; @@ -796,6 +850,9 @@ public: /// \brief Returns the value of the receiver at the time of this call. SVal getReceiverSVal() const; + /// \brief Return the value of 'self' if available. + SVal getSelfSVal() const; + /// \brief Get the interface for the receiver. /// /// This works whether this is an instance message or a class message. @@ -804,6 +861,9 @@ public: return getOriginExpr()->getReceiverInterface(); } + /// \brief Checks if the receiver refers to 'self' or 'super'. + bool isReceiverSelfOrSuper() const; + /// Returns how the message was written in the source (property access, /// subscript, or explicit message send). ObjCMessageKind getMessageKind() const; @@ -879,6 +939,13 @@ class CallEventManager { return new (allocate()) T(A1, A2, A3, St, LCtx); } + template <typename T, typename Arg1, typename Arg2, typename Arg3, + typename Arg4> + T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St, + const LocationContext *LCtx) { + return new (allocate()) T(A1, A2, A3, A4, St, LCtx); + } + public: CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {} @@ -905,9 +972,9 @@ public: CallEventRef<CXXDestructorCall> getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, - const MemRegion *Target, ProgramStateRef State, - const LocationContext *LCtx) { - return create<CXXDestructorCall>(DD, Trigger, Target, State, LCtx); + const MemRegion *Target, bool IsBase, + ProgramStateRef State, const LocationContext *LCtx) { + return create<CXXDestructorCall>(DD, Trigger, Target, IsBase, State, LCtx); } CallEventRef<CXXAllocatorCall> 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 8c8e82c..4558cd9 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 @@ -16,10 +16,57 @@ #define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" namespace clang { namespace ento { + /// Declares an immutable map of type \p NameTy, suitable for placement into + /// the ProgramState. This is implementing using llvm::ImmutableMap. + /// + /// \code + /// State = State->set<Name>(K, V); + /// const Value *V = State->get<Name>(K); // Returns NULL if not in the map. + /// State = State->remove<Name>(K); + /// NameTy Map = State->get<Name>(); + /// \endcode + /// + /// The macro should not be used inside namespaces, or for traits that must + /// be accessible from more than one translation unit. + #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \ + REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \ + CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value)) + + /// Declares an immutable set of type \p NameTy, suitable for placement into + /// the ProgramState. This is implementing using llvm::ImmutableSet. + /// + /// \code + /// State = State->add<Name>(E); + /// State = State->remove<Name>(E); + /// bool Present = State->contains<Name>(E); + /// NameTy Set = State->get<Name>(); + /// \endcode + /// + /// The macro should not be used inside namespaces, or for traits that must + /// be accessible from more than one translation unit. + #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \ + REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>) + + /// Declares an immutable list of type \p NameTy, suitable for placement into + /// the ProgramState. This is implementing using llvm::ImmutableList. + /// + /// \code + /// State = State->add<Name>(E); // Adds to the /end/ of the list. + /// bool Present = State->contains<Name>(E); + /// NameTy List = State->get<Name>(); + /// \endcode + /// + /// The macro should not be used inside namespaces, or for traits that must + /// be accessible from more than one translation unit. + #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \ + REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList<Elem>) + + class CheckerContext { ExprEngine &Eng; /// The current exploded(symbolic execution) graph node. @@ -64,6 +111,10 @@ public: return Eng.getStoreManager(); } + const AnalyzerOptions::ConfigTable &getConfig() const { + return Eng.getAnalysisManager().options.Config; + } + /// \brief Returns the previous node in the exploded graph, which includes /// the state of the program before the checker ran. Note, checkers should /// not retain the node in their state since the nodes might get invalidated. @@ -76,8 +127,8 @@ public: /// \brief Returns the number of times the current block has been visited /// along the analyzed path. - unsigned getCurrentBlockCount() const { - return NB.getContext().getCurrentBlockCount(); + unsigned blockCount() const { + return NB.getContext().blockCount(); } ASTContext &getASTContext() { @@ -96,6 +147,9 @@ public: return Pred->getStackFrame(); } + /// Return true if the current LocationContext has no caller context. + bool inTopFrame() const { return getLocationContext()->inTopFrame(); } + BugReporter &getBugReporter() { return Eng.getBugReporter(); } @@ -144,20 +198,15 @@ public: /// \brief Generates a new transition in the program state graph /// (ExplodedGraph). Uses the default CheckerContext predecessor node. /// - /// @param State The state of the generated node. + /// @param State The state of the generated node. If not specified, the state + /// will not be changed, but the new node will have the checker's tag. /// @param Tag The tag is used to uniquely identify the creation site. If no /// tag is specified, a default tag, unique to the given checker, /// will be used. Tags are used to prevent states generated at /// different sites from caching out. - ExplodedNode *addTransition(ProgramStateRef State, + ExplodedNode *addTransition(ProgramStateRef State = 0, const ProgramPointTag *Tag = 0) { - return addTransitionImpl(State, false, 0, Tag); - } - - /// \brief Generates a default transition (containing checker tag but no - /// checker state changes). - ExplodedNode *addTransition() { - return addTransition(getState()); + return addTransitionImpl(State ? State : getState(), false, 0, Tag); } /// \brief Generates a new transition with the given predecessor. @@ -167,25 +216,24 @@ public: /// @param Pred The transition will be generated from the specified Pred node /// to the newly generated node. /// @param Tag The tag to uniquely identify the creation site. - /// @param IsSink Mark the new node as sink, which will stop exploration of - /// the given path. ExplodedNode *addTransition(ProgramStateRef State, - ExplodedNode *Pred, - const ProgramPointTag *Tag = 0, - bool IsSink = false) { - return addTransitionImpl(State, IsSink, Pred, Tag); + ExplodedNode *Pred, + const ProgramPointTag *Tag = 0) { + return addTransitionImpl(State, false, Pred, Tag); } - /// \brief Generate a sink node. Generating sink stops exploration of the + /// \brief Generate a sink node. Generating a sink stops exploration of the /// given path. - ExplodedNode *generateSink(ProgramStateRef state = 0) { - return addTransitionImpl(state ? state : getState(), true); + ExplodedNode *generateSink(ProgramStateRef State = 0, + ExplodedNode *Pred = 0, + const ProgramPointTag *Tag = 0) { + return addTransitionImpl(State ? State : getState(), true, Pred, Tag); } /// \brief Emit the diagnostics report. - void EmitReport(BugReport *R) { + void emitReport(BugReport *R) { Changed = true; - Eng.getBugReporter().EmitReport(R); + Eng.getBugReporter().emitReport(R); } /// \brief Get the declaration of the called function (path-sensitive). @@ -194,17 +242,33 @@ public: /// \brief Get the name of the called function (path-sensitive). StringRef getCalleeName(const FunctionDecl *FunDecl) const; + /// \brief Get the identifier of the called function (path-sensitive). + const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const { + const FunctionDecl *FunDecl = getCalleeDecl(CE); + if (FunDecl) + return FunDecl->getIdentifier(); + else + return 0; + } + /// \brief Get the name of the called function (path-sensitive). StringRef getCalleeName(const CallExpr *CE) const { const FunctionDecl *FunDecl = getCalleeDecl(CE); return getCalleeName(FunDecl); } - /// Given a function declaration and a name checks if this is a C lib - /// function with the given name. - bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name); - static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name, - ASTContext &Context); + /// \brief Returns true if the callee is an externally-visible function in the + /// top-level namespace, such as \c malloc. + /// + /// If a name is provided, the function must additionally match the given + /// name. + /// + /// Note that this deliberately excludes C++ library functions in the \c std + /// namespace, but will include C library functions accessed through the + /// \c std namespace. This also does not check if the function is declared + /// as 'extern "C"', or if it uses C++ name mangling. + static bool isCLibraryFunction(const FunctionDecl *FD, + StringRef Name = StringRef()); /// \brief Depending on wither the location corresponds to a macro, return /// either the macro name or the token spelling. @@ -226,9 +290,15 @@ private: return Pred; Changed = true; - ExplodedNode *node = NB.generateNode(Tag ? Location.withTag(Tag) : Location, - State, - P ? P : Pred, MarkAsSink); + const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location); + if (!P) + P = Pred; + + ExplodedNode *node; + if (MarkAsSink) + node = NB.generateSink(LocalLoc, State, P); + else + node = NB.generateNode(LocalLoc, State, P); 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 631858d..4a78849 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 @@ -16,6 +16,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/Support/SaveAndRestore.h" namespace llvm { class APSInt; @@ -26,29 +27,83 @@ namespace ento { class SubEngine; +class ConditionTruthVal { + llvm::Optional<bool> Val; +public: + /// Construct a ConditionTruthVal indicating the constraint is constrained + /// to either true or false, depending on the boolean value provided. + ConditionTruthVal(bool constraint) : Val(constraint) {} + + /// Construct a ConstraintVal indicating the constraint is underconstrained. + ConditionTruthVal() {} + + /// Return true if the constraint is perfectly constrained to 'true'. + bool isConstrainedTrue() const { + return Val.hasValue() && Val.getValue(); + } + + /// Return true if the constraint is perfectly constrained to 'false'. + bool isConstrainedFalse() const { + return Val.hasValue() && !Val.getValue(); + } + + /// Return true if the constrained is perfectly constrained. + bool isConstrained() const { + return Val.hasValue(); + } + + /// Return true if the constrained is underconstrained and we do not know + /// if the constraint is true of value. + bool isUnderconstrained() const { + return !Val.hasValue(); + } +}; + class ConstraintManager { public: + ConstraintManager() : NotifyAssumeClients(true) {} + virtual ~ConstraintManager(); virtual ProgramStateRef assume(ProgramStateRef state, - DefinedSVal Cond, - bool Assumption) = 0; - - std::pair<ProgramStateRef, ProgramStateRef > - assumeDual(ProgramStateRef state, DefinedSVal Cond) - { - std::pair<ProgramStateRef, ProgramStateRef > res = - std::make_pair(assume(state, Cond, true), assume(state, Cond, false)); - - assert(!(!res.first && !res.second) && "System is over constrained."); - return res; + DefinedSVal Cond, + bool Assumption) = 0; + + typedef std::pair<ProgramStateRef, ProgramStateRef> ProgramStatePair; + + /// Returns a pair of states (StTrue, StFalse) where the given condition is + /// assumed to be true or false, respectively. + ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond) { + ProgramStateRef StTrue = assume(State, Cond, true); + + // If StTrue is infeasible, asserting the falseness of Cond is unnecessary + // because the existing constraints already establish this. + if (!StTrue) { + // FIXME: This is fairly expensive and should be disabled even in + // Release+Asserts builds. + assert(assume(State, Cond, false) && "System is over constrained."); + return ProgramStatePair((ProgramStateRef)NULL, State); + } + + ProgramStateRef StFalse = assume(State, Cond, false); + if (!StFalse) { + // We are careful to return the original state, /not/ StTrue, + // because we want to avoid having callers generate a new node + // in the ExplodedGraph. + return ProgramStatePair(State, (ProgramStateRef)NULL); + } + + return ProgramStatePair(StTrue, StFalse); } + /// \brief If a symbol is perfectly constrained to a constant, attempt + /// to return the concrete value. + /// + /// Note that a ConstraintManager is not obligated to return a concretized + /// value for a symbol, even if it is perfectly constrained. virtual const llvm::APSInt* getSymVal(ProgramStateRef state, - SymbolRef sym) const = 0; - - virtual bool isEqual(ProgramStateRef state, - SymbolRef sym, - const llvm::APSInt& V) const = 0; + SymbolRef sym) const { + return 0; + } virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper& SymReaper) = 0; @@ -59,20 +114,38 @@ public: const char *sep) = 0; virtual void EndPath(ProgramStateRef state) {} + + /// Convenience method to query the state to see if a symbol is null or + /// not null, or if neither assumption can be made. + ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym) { + llvm::SaveAndRestore<bool> DisableNotify(NotifyAssumeClients, false); + + return checkNull(State, Sym); + } protected: + /// A flag to indicate that clients should be notified of assumptions. + /// By default this is the case, but sometimes this needs to be restricted + /// to avoid infinite recursions within the ConstraintManager. + /// + /// Note that this flag allows the ConstraintManager to be re-entrant, + /// but not thread-safe. + bool NotifyAssumeClients; + /// canReasonAbout - Not all ConstraintManagers can accurately reason about /// all SVal values. This method returns true if the ConstraintManager can /// reasonably handle a given SVal value. This is typically queried by /// ExprEngine to determine if the value should be replaced with a /// conjured symbolic value in order to recover some precision. virtual bool canReasonAbout(SVal X) const = 0; + + /// Returns whether or not a symbol is known to be null ("true"), known to be + /// non-null ("false"), or may be either ("underconstrained"). + virtual ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym); }; -ConstraintManager* CreateBasicConstraintManager(ProgramStateManager& statemgr, - SubEngine &subengine); ConstraintManager* CreateRangeConstraintManager(ProgramStateManager& statemgr, - SubEngine &subengine); + 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 e75cdd8..b668640 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 @@ -80,10 +80,6 @@ private: /// usually because it could not reason about something. BlocksAborted blocksAborted; - /// The functions which have been analyzed through inlining. This is owned by - /// AnalysisConsumer. It can be null. - SetOfConstDecls *AnalyzedCallees; - /// The information about functions shared by the whole translation unit. /// (This data is owned by AnalysisConsumer.) FunctionSummariesTy *FunctionSummaries; @@ -101,19 +97,18 @@ private: ExplodedNode *Pred); private: - CoreEngine(const CoreEngine&); // Do not implement. - CoreEngine& operator=(const CoreEngine&); + CoreEngine(const CoreEngine &) LLVM_DELETED_FUNCTION; + void operator=(const CoreEngine &) LLVM_DELETED_FUNCTION; ExplodedNode *generateCallExitBeginNode(ExplodedNode *N); public: /// Construct a CoreEngine object to analyze the provided CFG. - CoreEngine(SubEngine& subengine, SetOfConstDecls *VisitedCallees, + CoreEngine(SubEngine& subengine, FunctionSummariesTy *FS) : SubEng(subengine), G(new ExplodedGraph()), WList(WorkList::makeDFS()), BCounterFactory(G->getAllocator()), - AnalyzedCallees(VisitedCallees), FunctionSummaries(FS){} /// getGraph - Returns the exploded graph. @@ -185,20 +180,18 @@ public: struct NodeBuilderContext { const CoreEngine &Eng; const CFGBlock *Block; - ExplodedNode *Pred; + const LocationContext *LC; NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N) - : Eng(E), Block(B), Pred(N) { assert(B); assert(!N->isSink()); } - - ExplodedNode *getPred() const { return Pred; } + : Eng(E), Block(B), LC(N->getLocationContext()) { assert(B); } /// \brief Return the CFGBlock associated with this builder. const CFGBlock *getBlock() const { return Block; } /// \brief Returns the number of times the current basic block has been /// visited on the exploded graph path. - unsigned getCurrentBlockCount() const { + unsigned blockCount() const { return Eng.WList->getBlockCounter().getNumVisited( - Pred->getLocationContext()->getCurrentStackFrame(), + LC->getCurrentStackFrame(), Block->getBlockID()); } }; @@ -265,14 +258,21 @@ public: virtual ~NodeBuilder() {} /// \brief Generates a node in the ExplodedGraph. + ExplodedNode *generateNode(const ProgramPoint &PP, + ProgramStateRef State, + ExplodedNode *Pred) { + return generateNodeImpl(PP, State, Pred, false); + } + + /// \brief Generates a sink in the ExplodedGraph. /// /// When a node is marked as sink, the exploration from the node is stopped - - /// the node becomes the last node on the path. - ExplodedNode *generateNode(const ProgramPoint &PP, + /// the node becomes the last node on the path and certain kinds of bugs are + /// suppressed. + ExplodedNode *generateSink(const ProgramPoint &PP, ProgramStateRef State, - ExplodedNode *Pred, - bool MarkAsSink = false) { - return generateNodeImpl(PP, State, Pred, MarkAsSink); + ExplodedNode *Pred) { + return generateNodeImpl(PP, State, Pred, true); } const ExplodedNodeSet &getResults() { @@ -317,13 +317,18 @@ public: NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet, const NodeBuilderContext &Ctx, ProgramPoint &L) : NodeBuilder(Pred, DstSet, Ctx), Location(L) {} + ExplodedNode *generateNode(ProgramStateRef State, ExplodedNode *Pred, - const ProgramPointTag *Tag = 0, - bool MarkAsSink = false) { - ProgramPoint LocalLoc = (Tag ? Location.withTag(Tag): Location); + const ProgramPointTag *Tag = 0) { + const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location); + return NodeBuilder::generateNode(LocalLoc, State, Pred); + } - ExplodedNode *N = generateNodeImpl(LocalLoc, State, Pred, MarkAsSink); + ExplodedNode *generateSink(ProgramStateRef State, ExplodedNode *Pred, + const ProgramPointTag *Tag = 0) { + const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location); + ExplodedNode *N = NodeBuilder::generateSink(LocalLoc, State, Pred); if (N && N->isSink()) sinksGenerated.push_back(N); return N; @@ -336,7 +341,7 @@ public: /// \class StmtNodeBuilder /// \brief This builder class is useful for generating nodes that resulted from -/// visiting a statement. The main difference from it's parent NodeBuilder is +/// visiting a statement. The main difference from its parent NodeBuilder is /// that it creates a statement specific ProgramPoint. class StmtNodeBuilder: public NodeBuilder { NodeBuilder *EnclosingBldr; @@ -363,22 +368,27 @@ public: virtual ~StmtNodeBuilder(); + using NodeBuilder::generateNode; + using NodeBuilder::generateSink; + ExplodedNode *generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, - bool MarkAsSink = false, const ProgramPointTag *tag = 0, ProgramPoint::Kind K = ProgramPoint::PostStmtKind){ const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, Pred->getLocationContext(), tag); - return generateNodeImpl(L, St, Pred, MarkAsSink); + return NodeBuilder::generateNode(L, St, Pred); } - ExplodedNode *generateNode(const ProgramPoint &PP, + ExplodedNode *generateSink(const Stmt *S, ExplodedNode *Pred, - ProgramStateRef State, - bool MarkAsSink = false) { - return generateNodeImpl(PP, State, Pred, MarkAsSink); + ProgramStateRef St, + const ProgramPointTag *tag = 0, + ProgramPoint::Kind K = ProgramPoint::PostStmtKind){ + const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, + Pred->getLocationContext(), tag); + return NodeBuilder::generateSink(L, St, Pred); } }; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h new file mode 100644 index 0000000..5ac97db --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h @@ -0,0 +1,52 @@ +//== DynamicTypeInfo.h - Runtime type information ----------------*- 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_SA_CORE_DYNAMICTYPEINFO_H +#define LLVM_CLANG_SA_CORE_DYNAMICTYPEINFO_H + +#include "clang/AST/Type.h" + +namespace clang { +namespace ento { + +/// \brief Stores the currently inferred strictest bound on the runtime type +/// of a region in a given state along the analysis path. +class DynamicTypeInfo { +private: + QualType T; + bool CanBeASubClass; + +public: + + DynamicTypeInfo() : T(QualType()) {} + DynamicTypeInfo(QualType WithType, bool CanBeSub = true) + : T(WithType), CanBeASubClass(CanBeSub) {} + + /// \brief Return false if no dynamic type info is available. + bool isValid() const { return !T.isNull(); } + + /// \brief Returns the currently inferred upper bound on the runtime type. + QualType getType() const { return T; } + + /// \brief Returns false if the type information is precise (the type T is + /// the only type in the lattice), true otherwise. + bool canBeASubClass() const { return CanBeASubClass; } + + void Profile(llvm::FoldingSetNodeID &ID) const { + ID.Add(T); + ID.AddInteger((unsigned)CanBeASubClass); + } + bool operator==(const DynamicTypeInfo &X) const { + return T == X.T && CanBeASubClass == X.CanBeASubClass; + } +}; + +} // end ento +} // end clang + +#endif 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 b80213e..eb9bd85 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 @@ -33,10 +33,11 @@ class SValBuilder; /// other things. class EnvironmentEntry : public std::pair<const Stmt*, const StackFrameContext *> { + friend class EnvironmentManager; + EnvironmentEntry makeLocation() const; + public: - EnvironmentEntry(const Stmt *s, const LocationContext *L) - : std::pair<const Stmt*, - const StackFrameContext*>(s, L ? L->getCurrentStackFrame():0) {} + EnvironmentEntry(const Stmt *s, const LocationContext *L); const Stmt *getStmt() const { return first; } const LocationContext *getLocationContext() const { return second; } @@ -76,9 +77,7 @@ public: /// Fetches the current binding of the expression in the /// Environment. - SVal getSVal(const EnvironmentEntry &E, - SValBuilder &svalBuilder, - bool useOnlyDirectBindings = false) const; + SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const; /// Profile - Profile the contents of an Environment object for use /// in a FoldingSet. 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 1052d94..b112e66 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 @@ -60,45 +60,50 @@ class ExplodedNode : public llvm::FoldingSetNode { friend class SwitchNodeBuilder; friend class EndOfFunctionNodeBuilder; + /// Efficiently stores a list of ExplodedNodes, or an optional flag. + /// + /// NodeGroup provides opaque storage for a list of ExplodedNodes, optimizing + /// for the case when there is only one node in the group. This is a fairly + /// common case in an ExplodedGraph, where most nodes have only one + /// predecessor and many have only one successor. It can also be used to + /// store a flag rather than a node list, which ExplodedNode uses to mark + /// whether a node is a sink. If the flag is set, the group is implicitly + /// empty and no nodes may be added. class NodeGroup { - enum { Size1 = 0x0, SizeOther = 0x1, AuxFlag = 0x2, Mask = 0x3 }; + // Conceptually a discriminated union. If the low bit is set, the node is + // a sink. If the low bit is not set, the pointer refers to the storage + // for the nodes in the group. + // This is not a PointerIntPair in order to keep the storage type opaque. uintptr_t P; - - unsigned getKind() const { - return P & 0x1; - } - - void *getPtr() const { - assert (!getFlag()); - return reinterpret_cast<void*>(P & ~Mask); - } - - ExplodedNode *getNode() const { - return reinterpret_cast<ExplodedNode*>(getPtr()); - } public: - NodeGroup() : P(0) {} + NodeGroup(bool Flag = false) : P(Flag) { + assert(getFlag() == Flag); + } - ExplodedNode **begin() const; + ExplodedNode * const *begin() const; - ExplodedNode **end() const; + ExplodedNode * const *end() const; unsigned size() const; - bool empty() const { return (P & ~Mask) == 0; } + bool empty() const { return P == 0 || getFlag() != 0; } + /// Adds a node to the list. + /// + /// The group must not have been created with its flag set. void addNode(ExplodedNode *N, ExplodedGraph &G); + /// Replaces the single node in this group with a new node. + /// + /// Note that this should only be used when you know the group was not + /// created with its flag set, and that the group is empty or contains + /// only a single node. void replaceNode(ExplodedNode *node); - void setFlag() { - assert(P == 0); - P = AuxFlag; - } - + /// Returns whether this group was created with its flag set. bool getFlag() const { - return P & AuxFlag ? true : false; + return (P & 1); } }; @@ -119,9 +124,8 @@ public: explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state, bool IsSink) - : Location(loc), State(state) { - if (IsSink) - Succs.setFlag(); + : Location(loc), State(state), Succs(IsSink) { + assert(isSink() == IsSink); } ~ExplodedNode() {} @@ -190,9 +194,9 @@ public: } // Iterators over successor and predecessor vertices. - typedef ExplodedNode** succ_iterator; + typedef ExplodedNode* const * succ_iterator; typedef const ExplodedNode* const * const_succ_iterator; - typedef ExplodedNode** pred_iterator; + typedef ExplodedNode* const * pred_iterator; typedef const ExplodedNode* const * const_pred_iterator; pred_iterator pred_begin() { return Preds.begin(); } @@ -278,11 +282,13 @@ protected: /// A list of nodes that can be reused. NodeVector FreeNodes; - /// A flag that indicates whether nodes should be recycled. - bool reclaimNodes; + /// Determines how often nodes are reclaimed. + /// + /// If this is 0, nodes will never be reclaimed. + unsigned ReclaimNodeInterval; /// Counter to determine when to reclaim nodes. - unsigned reclaimCounter; + unsigned ReclaimCounter; public: @@ -370,7 +376,9 @@ public: /// Enable tracking of recently allocated nodes for potential reclamation /// when calling reclaimRecentlyAllocatedNodes(). - void enableNodeReclamation() { reclaimNodes = true; } + void enableNodeReclamation(unsigned Interval) { + ReclaimCounter = ReclaimNodeInterval = Interval; + } /// Reclaim "uninteresting" nodes created since the last time this method /// was called. 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 4addb9d..78b2542 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 @@ -16,6 +16,7 @@ #ifndef LLVM_CLANG_GR_EXPRENGINE #define LLVM_CLANG_GR_EXPRENGINE +#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" @@ -70,17 +71,14 @@ class ExprEngine : public SubEngine { /// variables and symbols (as determined by a liveness analysis). ProgramStateRef CleanedState; - /// currentStmt - The current block-level statement. - const Stmt *currentStmt; - unsigned int currentStmtIdx; - const NodeBuilderContext *currentBuilderContext; - - /// Obj-C Class Identifiers. - IdentifierInfo* NSExceptionII; - - /// Obj-C Selectors. - Selector* NSExceptionInstanceRaiseSelectors; - Selector RaiseSel; + /// currStmt - The current block-level statement. + const Stmt *currStmt; + unsigned int currStmtIdx; + const NodeBuilderContext *currBldrCtx; + + /// Helper object to determine if an Objective-C message expression + /// implicitly never returns. + ObjCNoReturn ObjCNoRet; /// Whether or not GC is enabled in this analysis. bool ObjCGCEnabled; @@ -90,9 +88,13 @@ class ExprEngine : public SubEngine { /// destructor is called before the rest of the ExprEngine is destroyed. GRBugReporter BR; + /// The functions which have been analyzed through inlining. This is owned by + /// AnalysisConsumer. It can be null. + SetOfConstDecls *VisitedCallees; + public: ExprEngine(AnalysisManager &mgr, bool gcEnabled, - SetOfConstDecls *VisitedCallees, + SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS); ~ExprEngine(); @@ -126,8 +128,8 @@ public: BugReporter& getBugReporter() { return BR; } const NodeBuilderContext &getBuilderContext() { - assert(currentBuilderContext); - return *currentBuilderContext; + assert(currBldrCtx); + return *currBldrCtx; } bool isObjCGCEnabled() { return ObjCGCEnabled; } @@ -165,8 +167,12 @@ public: /// are usually reported here). /// \param K - In some cases it is possible to use PreStmt kind. (Do /// not use it unless you know what you are doing.) + /// If the ReferenceStmt is NULL, everything is this and parent contexts is + /// considered live. + /// If the stack frame context is NULL, everything on stack is considered + /// dead. void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, - const Stmt *ReferenceStmt, const LocationContext *LC, + const Stmt *ReferenceStmt, const StackFrameContext *LC, const Stmt *DiagnosticStmt, ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind); @@ -192,7 +198,8 @@ public: /// Called by CoreEngine when processing the entrance of a CFGBlock. virtual void processCFGBlockEntrance(const BlockEdge &L, - NodeBuilderWithSinks &nodeBuilder); + NodeBuilderWithSinks &nodeBuilder, + ExplodedNode *Pred); /// ProcessBranch - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a branch condition. @@ -213,7 +220,13 @@ public: /// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path /// nodes when the control reaches the end of a function. - void processEndOfFunction(NodeBuilderContext& BC); + void processEndOfFunction(NodeBuilderContext& BC, + ExplodedNode *Pred); + + /// Remove dead bindings/symbols before exiting a function. + void removeDeadOnEndOfFunction(NodeBuilderContext& BC, + ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// Generate the entry node of the callee. void processCallEnter(CallEnter CE, ExplodedNode *Pred); @@ -258,9 +271,6 @@ public: BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); } - const BasicValueFactory& getBasicVals() const { - return StateMgr.getBasicVals(); - } // FIXME: Remove when we migrate over to just using ValueManager. SymbolManager& getSymbolManager() { return SymMgr; } @@ -283,13 +293,14 @@ public: ExplodedNode *Pred, ExplodedNodeSet &Dst); - /// VisitAsmStmt - Transfer function logic for inline asm. - void VisitAsmStmt(const AsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst); + /// VisitGCCAsmStmt - Transfer function logic for inline asm. + void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// VisitMSAsmStmt - Transfer function logic for MS inline asm. void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst); - + /// VisitBlockExpr - Transfer function logic for BlockExprs. void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst); @@ -380,8 +391,8 @@ public: void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst); - void VisitCXXDestructor(QualType ObjectType, - const MemRegion *Dest, const Stmt *S, + void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, + const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst); void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, @@ -395,14 +406,14 @@ public: ExplodedNode *Pred, ExplodedNodeSet &Dst); - /// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic + /// evalEagerlyAssumeBinOpBifurcation - 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 evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex); std::pair<const ProgramPointTag *, const ProgramPointTag*> - getEagerlyAssumeTags(); + geteagerlyAssumeBinOpBifurcationTags(); SVal evalMinus(SVal X) { return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X; @@ -433,7 +444,8 @@ protected: /// 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, - SVal location, SVal Val, bool atDeclInit = false); + SVal location, SVal Val, bool atDeclInit = false, + const ProgramPoint *PP = 0); public: // FIXME: 'tag' should be removed, and a LocationContext should be used @@ -490,6 +502,10 @@ private: ProgramStateRef St, SVal location, const ProgramPointTag *tag, bool isLoad); + /// Count the stack depth and determine if the call is recursive. + void examineStackFrames(const Decl *D, const LocationContext *LCtx, + bool &IsRecursive, unsigned &StackDepth); + bool shouldInlineDecl(const Decl *D, ExplodedNode *Pred); bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State); @@ -510,6 +526,8 @@ private: /// Traits for storing the call processing policy inside GDM. /// The GDM stores the corresponding CallExpr pointer. +// FIXME: This does not use the nice trait macros because it must be accessible +// from multiple translation units. struct ReplayWithoutInlining{}; template <> struct ProgramStateTrait<ReplayWithoutInlining> : 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 8044ed8..34fbc3c 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 @@ -99,11 +99,11 @@ public: // Untyped regions. SymbolicRegionKind, AllocaRegionKind, - BlockDataRegionKind, // Typed regions. BEG_TYPED_REGIONS, FunctionTextRegionKind = BEG_TYPED_REGIONS, BlockTextRegionKind, + BlockDataRegionKind, BEG_TYPED_VALUE_REGIONS, CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS, CXXThisRegionKind, @@ -140,6 +140,9 @@ public: const MemRegion *getBaseRegion() const; + /// Check if the region is a subregion of the given region. + virtual bool isSubRegionOf(const MemRegion *R) const; + const MemRegion *StripCasts(bool StripBaseCasts = true) const; bool hasGlobalsOrParametersStorage() const; @@ -171,8 +174,6 @@ public: template<typename RegionTy> const RegionTy* getAs() const; virtual bool isBoundable() const { return false; } - - static bool classof(const MemRegion*) { return true; } }; /// MemSpaceRegion - A memory region that represents a "memory space"; @@ -416,7 +417,7 @@ public: MemRegionManager* getMemRegionManager() const; - bool isSubRegionOf(const MemRegion* R) const; + virtual bool isSubRegionOf(const MemRegion* R) const; static bool classof(const MemRegion* R) { return R->getKind() > END_MEMSPACES; @@ -530,16 +531,28 @@ public: /// FunctionTextRegion - A region that represents code texts of function. class FunctionTextRegion : public CodeTextRegion { - const FunctionDecl *FD; + const NamedDecl *FD; public: - FunctionTextRegion(const FunctionDecl *fd, const MemRegion* sreg) - : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {} + FunctionTextRegion(const NamedDecl *fd, const MemRegion* sreg) + : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) { + assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd)); + } QualType getLocationType() const { - return getContext().getPointerType(FD->getType()); + const ASTContext &Ctx = getContext(); + if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) { + return Ctx.getPointerType(D->getType()); + } + + assert(isa<ObjCMethodDecl>(FD)); + assert(false && "Getting the type of ObjCMethod is not supported yet"); + + // TODO: We might want to return a different type here (ex: id (*ty)(...)) + // depending on how it is used. + return QualType(); } - - const FunctionDecl *getDecl() const { + + const NamedDecl *getDecl() const { return FD; } @@ -547,7 +560,7 @@ public: void Profile(llvm::FoldingSetNodeID& ID) const; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD, + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD, const MemRegion*); static bool classof(const MemRegion* R) { @@ -603,7 +616,7 @@ public: /// which correspond to "code+data". The distinction is important, because /// like a closure a block captures the values of externally referenced /// variables. -class BlockDataRegion : public SubRegion { +class BlockDataRegion : public TypedRegion { friend class MemRegionManager; const BlockTextRegion *BC; const LocationContext *LC; // Can be null */ @@ -612,13 +625,15 @@ class BlockDataRegion : public SubRegion { BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, const MemRegion *sreg) - : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), + : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0), OriginalVars(0) {} public: const BlockTextRegion *getCodeRegion() const { return BC; } const BlockDecl *getDecl() const { return BC->getDecl(); } + + QualType getLocationType() const { return BC->getLocationType(); } class referenced_vars_iterator { const MemRegion * const *R; @@ -1212,7 +1227,7 @@ public: return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion); } - const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD); + const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD); const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, CanQualType locTy, AnalysisDeclContext *AC); diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index b0c51dd..86c94de 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines SymbolRef, ExprBindKey, and ProgramState*. +// This file defines the state of the program along the analysisa path. // //===----------------------------------------------------------------------===// @@ -16,6 +16,7 @@ #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" @@ -39,7 +40,7 @@ class CallEvent; class CallEventManager; typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&, - SubEngine&); + SubEngine*); typedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&); //===----------------------------------------------------------------------===// @@ -56,32 +57,6 @@ template <typename T> struct ProgramStateTrait { } }; -/// \class Stores the dynamic type information. -/// Information about type of an object at runtime. This is used by dynamic -/// dispatch implementation. -class DynamicTypeInfo { - QualType T; - bool CanBeASubClass; - -public: - DynamicTypeInfo() : T(QualType()) {} - DynamicTypeInfo(QualType WithType, bool CanBeSub = true) - : T(WithType), CanBeASubClass(CanBeSub) {} - - bool isValid() const { return !T.isNull(); } - - QualType getType() const { return T; } - bool canBeASubClass() const { return CanBeASubClass; } - - void Profile(llvm::FoldingSetNodeID &ID) const { - T.Profile(ID); - ID.AddInteger((unsigned)CanBeASubClass); - } - bool operator==(const DynamicTypeInfo &X) const { - return T == X.T && CanBeASubClass == X.CanBeASubClass; - } -}; - /// \class ProgramState /// ProgramState - This class encapsulates: /// @@ -100,7 +75,7 @@ public: typedef llvm::ImmutableMap<void*, void*> GenericDataMap; private: - void operator=(const ProgramState& R) const; // Do not implement. + void operator=(const ProgramState& R) LLVM_DELETED_FUNCTION; friend class ProgramStateManager; friend class ExplodedGraph; @@ -130,7 +105,12 @@ public: ~ProgramState(); /// Return the ProgramStateManager associated with this state. - ProgramStateManager &getStateManager() const { return *stateMgr; } + ProgramStateManager &getStateManager() const { + return *stateMgr; + } + + /// Return the ConstraintManager. + ConstraintManager &getConstraintManager() const; /// getEnvironment - Return the environment associated with this state. /// The environment is the mapping from expressions to values. @@ -210,11 +190,13 @@ public: // Binding and retrieving values to/from the environment and symbolic store. //==---------------------------------------------------------------------==// - /// BindCompoundLiteral - Return the state that has the bindings currently - /// in this state plus the bindings for the CompoundLiteral. + /// \brief Create a new state with the specified CompoundLiteral binding. + /// \param CL the compound literal expression (the binding key) + /// \param LC the LocationContext of the binding + /// \param V the value to bind. ProgramStateRef bindCompoundLiteral(const CompoundLiteralExpr *CL, - const LocationContext *LC, - SVal V) const; + const LocationContext *LC, + SVal V) const; /// Create a new state by binding the value 'V' to the statement 'S' in the /// state's environment. @@ -226,18 +208,16 @@ public: ProgramStateRef bindExprAndLocation(const Stmt *S, const LocationContext *LCtx, SVal location, SVal V) const; - - ProgramStateRef bindDecl(const VarRegion *VR, SVal V) const; - ProgramStateRef bindDeclWithNoInit(const VarRegion *VR) const; - - ProgramStateRef bindLoc(Loc location, SVal V) const; + ProgramStateRef bindLoc(Loc location, + SVal V, + bool notifyChanges = true) const; ProgramStateRef bindLoc(SVal location, SVal V) const; ProgramStateRef bindDefault(SVal loc, SVal V) const; - ProgramStateRef unbindLoc(Loc LV) const; + ProgramStateRef killBinding(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 @@ -271,11 +251,8 @@ public: /// Get the lvalue for an array index. SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const; - 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, const LocationContext *LCtx, - bool useOnlyDirectBindings = false) const; + SVal getSVal(const Stmt *S, const LocationContext *LCtx) const; SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const; @@ -469,7 +446,7 @@ public: StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, llvm::BumpPtrAllocator& alloc, - SubEngine &subeng); + SubEngine *subeng); ~ProgramStateManager(); @@ -481,9 +458,6 @@ public: BasicValueFactory &getBasicVals() { return svalBuilder->getBasicValueFactory(); } - const BasicValueFactory& getBasicVals() const { - return svalBuilder->getBasicValueFactory(); - } SValBuilder &getSValBuilder() { return *svalBuilder; @@ -515,10 +489,6 @@ public: const StackFrameContext *LCtx, SymbolReaper& SymReaper); - /// Marshal a new state for the callee in another translation unit. - /// 'state' is owned by the caller's engine. - ProgramStateRef MarshalState(ProgramStateRef state, const StackFrameContext *L); - public: SVal ArrayToPointer(Loc Array) { @@ -617,10 +587,6 @@ public: return ProgramStateTrait<T>::MakeContext(p); } - const llvm::APSInt* getSymVal(ProgramStateRef St, SymbolRef sym) { - return ConstraintMgr->getSymVal(St, sym); - } - void EndPath(ProgramStateRef St) { ConstraintMgr->EndPath(St); } @@ -631,6 +597,10 @@ public: // Out-of-line method definitions for ProgramState. //===----------------------------------------------------------------------===// +inline ConstraintManager &ProgramState::getConstraintManager() const { + return stateMgr->getConstraintManager(); +} + inline const VarRegion* ProgramState::getRegion(const VarDecl *D, const LocationContext *LC) const { @@ -695,15 +665,10 @@ inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) c return UnknownVal(); } -inline const llvm::APSInt *ProgramState::getSymVal(SymbolRef sym) const { - return getStateManager().getSymVal(this, sym); -} - -inline SVal ProgramState::getSVal(const Stmt *Ex, const LocationContext *LCtx, - bool useOnlyDirectBindings) const{ +inline SVal ProgramState::getSVal(const Stmt *Ex, + const LocationContext *LCtx) const{ return Env.getSVal(EnvironmentEntry(Ex, LCtx), - *getStateManager().svalBuilder, - useOnlyDirectBindings); + *getStateManager().svalBuilder); } inline SVal @@ -821,7 +786,7 @@ public: bool scan(const SymExpr *sym); }; -} // end GR namespace +} // end ento namespace } // end clang namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h index 1c7bedb..ea2a852 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h @@ -31,6 +31,26 @@ namespace clang { namespace ento { template <typename T> struct ProgramStatePartialTrait; + /// Declares a program state trait for type \p Type called \p Name, and + /// introduce a typedef named \c NameTy. + /// The macro should not be used inside namespaces, or for traits that must + /// be accessible from more than one translation unit. + #define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \ + namespace { \ + class Name {}; \ + typedef Type Name ## Ty; \ + } \ + namespace clang { \ + namespace ento { \ + template <> \ + struct ProgramStateTrait<Name> \ + : public ProgramStatePartialTrait<Name ## Ty> { \ + static void *GDMIndex() { static int Index; return &Index; } \ + }; \ + } \ + } + + // Partial-specialization for ImmutableMap. template <typename Key, typename Data, typename Info> @@ -71,6 +91,15 @@ namespace ento { } }; + /// Helper for registering a map trait. + /// + /// If the map type were written directly in the invocation of + /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments + /// would be treated as a macro argument separator, which is wrong. + /// This allows the user to specify a map type in a way that the preprocessor + /// can deal with. + #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value> + // Partial-specialization for ImmutableSet. @@ -113,6 +142,7 @@ namespace ento { } }; + // Partial-specialization for ImmutableList. template <typename T> @@ -150,6 +180,7 @@ namespace ento { delete (typename data_type::Factory*) Ctx; } }; + // Partial specialization for bool. template <> struct ProgramStatePartialTrait<bool> { 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 83c3a56..5d72e73 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 @@ -72,7 +72,7 @@ public: virtual ~SValBuilder() {} bool haveSameType(const SymExpr *Sym1, const SymExpr *Sym2) { - return haveSameType(Sym1->getType(Context), Sym2->getType(Context)); + return haveSameType(Sym1->getType(), Sym2->getType()); } bool haveSameType(QualType Ty1, QualType Ty2) { @@ -142,19 +142,19 @@ public: // Forwarding methods to SymbolManager. - const SymbolConjured* getConjuredSymbol(const Stmt *stmt, - const LocationContext *LCtx, - QualType type, - unsigned visitCount, - const void *symbolTag = 0) { - return SymMgr.getConjuredSymbol(stmt, LCtx, type, visitCount, symbolTag); + const SymbolConjured* conjureSymbol(const Stmt *stmt, + const LocationContext *LCtx, + QualType type, + unsigned visitCount, + const void *symbolTag = 0) { + return SymMgr.conjureSymbol(stmt, LCtx, type, visitCount, symbolTag); } - const SymbolConjured* getConjuredSymbol(const Expr *expr, - const LocationContext *LCtx, - unsigned visitCount, - const void *symbolTag = 0) { - return SymMgr.getConjuredSymbol(expr, LCtx, visitCount, symbolTag); + const SymbolConjured* conjureSymbol(const Expr *expr, + const LocationContext *LCtx, + unsigned visitCount, + const void *symbolTag = 0) { + return SymMgr.conjureSymbol(expr, LCtx, visitCount, symbolTag); } /// Construct an SVal representing '0' for the specified type. @@ -169,20 +169,20 @@ public: /// The advantage of symbols derived/built from other symbols is that we /// preserve the relation between related(or even equivalent) expressions, so /// conjured symbols should be used sparingly. - DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag, - const Expr *expr, - const LocationContext *LCtx, - unsigned count); - DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag, - const Expr *expr, - const LocationContext *LCtx, - QualType type, - unsigned count); + DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, + const Expr *expr, + const LocationContext *LCtx, + unsigned count); + DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, + const Expr *expr, + const LocationContext *LCtx, + QualType type, + unsigned count); - DefinedOrUnknownSVal getConjuredSymbolVal(const Stmt *stmt, - const LocationContext *LCtx, - QualType type, - unsigned visitCount); + DefinedOrUnknownSVal conjureSymbolVal(const Stmt *stmt, + const LocationContext *LCtx, + QualType type, + unsigned visitCount); /// \brief Conjure a symbol representing heap allocated memory region. /// /// Note, the expression should represent a location. @@ -227,7 +227,7 @@ public: BasicVals.getValue(integer->getValue(), integer->getType()->isUnsignedIntegerOrEnumerationType())); } - + nonloc::ConcreteInt makeBoolVal(const ObjCBoolLiteralExpr *boolean) { return makeTruthVal(boolean->getValue(), boolean->getType()); } @@ -262,11 +262,6 @@ public: BasicVals.getIntWithPtrWidth(integer, isUnsigned)); } - NonLoc makeIntVal(uint64_t integer, unsigned bitWidth, bool isUnsigned) { - return nonloc::ConcreteInt( - BasicVals.getValue(integer, bitWidth, isUnsigned)); - } - NonLoc makeLocAsInteger(Loc loc, unsigned bits) { return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(loc, bits)); } 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 e0b5f64..c2134cf 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 @@ -154,9 +154,6 @@ public: SymExpr::symbol_iterator symbol_end() const { return SymExpr::symbol_end(); } - - // Implement isa<T> support. - static inline bool classof(const SVal*) { return true; } }; @@ -257,7 +254,7 @@ public: namespace nonloc { -enum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind, +enum Kind { ConcreteIntKind, SymbolValKind, LocAsIntegerKind, CompoundValKind, LazyCompoundValKind }; /// \brief Represents symbolic expression. 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 138a590..979546b 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 @@ -25,6 +25,7 @@ namespace clang { class Stmt; class Expr; class ObjCIvarDecl; +class CXXBasePath; class StackFrameContext; namespace ento { @@ -67,15 +68,26 @@ public: virtual StoreRef Bind(Store store, Loc loc, SVal val) = 0; virtual StoreRef BindDefault(Store store, const MemRegion *R, SVal V); - virtual StoreRef Remove(Store St, Loc L) = 0; - /// BindCompoundLiteral - Return the store that has the bindings currently - /// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region - /// for the compound literal and 'BegInit' and 'EndInit' represent an - /// array of initializer values. - virtual StoreRef BindCompoundLiteral(Store store, - const CompoundLiteralExpr *cl, - const LocationContext *LC, SVal v) = 0; + /// \brief Create a new store with the specified binding removed. + /// \param ST the original store, that is the basis for the new store. + /// \param L the location whose binding should be removed. + virtual StoreRef killBinding(Store ST, Loc L) = 0; + + /// \brief Create a new store that binds a value to a compound literal. + /// + /// \param ST The original store whose bindings are the basis for the new + /// store. + /// + /// \param CL The compound literal to bind (the binding key). + /// + /// \param LC The LocationContext for the binding. + /// + /// \param V The value to bind to the compound literal. + virtual StoreRef bindCompoundLiteral(Store ST, + const CompoundLiteralExpr *CL, + const LocationContext *LC, + SVal V) = 0; /// getInitialStore - Returns the initial "empty" store representing the /// value bindings upon entry to an analyzed function. @@ -114,11 +126,15 @@ public: /// conversions between arrays and pointers. virtual SVal ArrayToPointer(Loc Array) = 0; - /// Evaluates DerivedToBase casts. - SVal evalDerivedToBase(SVal derived, const CastExpr *Cast); + /// Evaluates a chain of derived-to-base casts through the path specified in + /// \p Cast. + SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast); + + /// Evaluates a chain of derived-to-base casts through the specified path. + SVal evalDerivedToBase(SVal Derived, const CXXBasePath &CastPath); /// Evaluates a derived-to-base cast through a single level of derivation. - virtual SVal evalDerivedToBase(SVal derived, QualType derivedPtrType) = 0; + SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType); /// \brief Evaluates C++ dynamic_cast cast. /// The callback may result in the following 3 scenarios: @@ -128,8 +144,7 @@ public: /// enough info to determine if the cast will succeed at run time). /// The function returns an SVal representing the derived class; it's /// valid only if Failed flag is set to false. - virtual SVal evalDynamicCast(SVal base, QualType derivedPtrType, - bool &Failed) = 0; + SVal evalDynamicCast(SVal Base, QualType DerivedPtrType, bool &Failed); const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T); @@ -141,10 +156,6 @@ public: virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, 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; 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 68b81f1..1e71077 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 @@ -60,7 +60,8 @@ public: /// SubEngine is expected to populate dstNodes with new nodes representing /// updated analysis state, or generate no nodes at all if it doesn't. virtual void processCFGBlockEntrance(const BlockEdge &L, - NodeBuilderWithSinks &nodeBuilder) = 0; + NodeBuilderWithSinks &nodeBuilder, + ExplodedNode *Pred) = 0; /// Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a branch condition. @@ -81,7 +82,8 @@ public: /// Called by CoreEngine. Used to generate end-of-path /// nodes when the control reaches the end of a function. - virtual void processEndOfFunction(NodeBuilderContext& BC) = 0; + virtual void processEndOfFunction(NodeBuilderContext& BC, + ExplodedNode *Pred) = 0; // Generate the entry node of the callee. virtual void processCallEnter(CallEnter CE, ExplodedNode *Pred) = 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 5d27f86..873f773 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 @@ -65,12 +65,9 @@ public: virtual void dumpToStream(raw_ostream &os) const {} - virtual QualType getType(ASTContext&) const = 0; + virtual QualType getType() const = 0; virtual void Profile(llvm::FoldingSetNodeID& profile) = 0; - // Implement isa<T> support. - static inline bool classof(const SymExpr*) { return true; } - /// \brief Iterator over symbols that the current symbol depends on. /// /// For SymbolData, it's the symbol itself; for expressions, it's the @@ -144,7 +141,7 @@ public: virtual void dumpToStream(raw_ostream &os) const; - QualType getType(ASTContext&) const; + QualType getType() const; // Implement isa<T> support. static inline bool classof(const SymExpr *SE) { @@ -173,7 +170,7 @@ public: unsigned getCount() const { return Count; } const void *getTag() const { return SymbolTag; } - QualType getType(ASTContext&) const; + QualType getType() const; virtual void dumpToStream(raw_ostream &os) const; @@ -211,7 +208,7 @@ public: SymbolRef getParentSymbol() const { return parentSymbol; } const TypedValueRegion *getRegion() const { return R; } - QualType getType(ASTContext&) const; + QualType getType() const; virtual void dumpToStream(raw_ostream &os) const; @@ -244,7 +241,7 @@ public: const SubRegion *getRegion() const { return R; } - QualType getType(ASTContext&) const; + QualType getType() const; virtual void dumpToStream(raw_ostream &os) const; @@ -283,7 +280,7 @@ public: unsigned getCount() const { return Count; } const void *getTag() const { return Tag; } - QualType getType(ASTContext&) const; + QualType getType() const; virtual void dumpToStream(raw_ostream &os) const; @@ -320,7 +317,7 @@ public: SymbolCast(const SymExpr *In, QualType From, QualType To) : SymExpr(CastSymbolKind), Operand(In), FromTy(From), ToTy(To) { } - QualType getType(ASTContext &C) const { return ToTy; } + QualType getType() const { return ToTy; } const SymExpr *getOperand() const { return Operand; } @@ -358,7 +355,7 @@ 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() const { return T; } BinaryOperator::Opcode getOpcode() const { return Op; } @@ -399,7 +396,7 @@ public: const SymExpr *rhs, QualType t) : SymExpr(IntSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {} - QualType getType(ASTContext &C) const { return T; } + QualType getType() const { return T; } BinaryOperator::Opcode getOpcode() const { return Op; } @@ -446,7 +443,7 @@ 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() const { return T; } virtual void dumpToStream(raw_ostream &os) const; @@ -495,18 +492,17 @@ public: /// \brief Make a unique symbol for MemRegion R according to its kind. const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R); - const SymbolConjured* getConjuredSymbol(const Stmt *E, - const LocationContext *LCtx, - QualType T, - unsigned VisitCount, - const void *SymbolTag = 0); + const SymbolConjured* conjureSymbol(const Stmt *E, + const LocationContext *LCtx, + QualType T, + unsigned VisitCount, + const void *SymbolTag = 0); - const SymbolConjured* getConjuredSymbol(const Expr *E, - const LocationContext *LCtx, - unsigned VisitCount, - const void *SymbolTag = 0) { - return getConjuredSymbol(E, LCtx, E->getType(), - VisitCount, SymbolTag); + const SymbolConjured* conjureSymbol(const Expr *E, + const LocationContext *LCtx, + unsigned VisitCount, + const void *SymbolTag = 0) { + return conjureSymbol(E, LCtx, E->getType(), VisitCount, SymbolTag); } const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol, @@ -541,7 +537,7 @@ public: const SymExpr *rhs, QualType t); QualType getType(const SymExpr *SE) const { - return SE->getType(Ctx); + return SE->getType(); } /// \brief Add artificial symbol dependency. @@ -584,9 +580,11 @@ public: /// /// If the statement is NULL, everything is this and parent contexts is /// considered live. - SymbolReaper(const LocationContext *ctx, const Stmt *s, SymbolManager& symmgr, + /// If the stack frame context is NULL, everything on stack is considered + /// dead. + SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, SymbolManager& symmgr, StoreManager &storeMgr) - : LCtx(ctx->getCurrentStackFrame()), Loc(s), SymMgr(symmgr), + : LCtx(Ctx), Loc(s), SymMgr(symmgr), reapedStore(0, storeMgr) {} ~SymbolReaper() {} diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h index 53205d3..c274cea 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h @@ -22,6 +22,8 @@ namespace ento { /// The GDM component containing the tainted root symbols. We lazily infer the /// taint of the dependent symbols. Currently, this is a map from a symbol to /// tag kind. TODO: Should support multiple tag kinds. +// FIXME: This does not use the nice trait macros because it must be accessible +// from multiple translation units. struct TaintMap {}; typedef llvm::ImmutableMap<SymbolRef, TaintTagType> TaintMapImpl; template<> struct ProgramStateTrait<TaintMap> diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/CommandLineClangTool.h b/contrib/llvm/tools/clang/include/clang/Tooling/CommandLineClangTool.h deleted file mode 100644 index c29c302..0000000 --- a/contrib/llvm/tools/clang/include/clang/Tooling/CommandLineClangTool.h +++ /dev/null @@ -1,80 +0,0 @@ -//===- CommandLineClangTool.h - command-line clang tools driver -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the CommandLineClangTool class used to run clang -// tools as separate command-line applications with a consistent common -// interface for handling compilation database and input files. -// -// It provides a common subset of command-line options, common algorithm -// for locating a compilation database and source files, and help messages -// for the basic command-line interface. -// -// It creates a CompilationDatabase, initializes a ClangTool and runs a -// user-specified FrontendAction over all TUs in which the given files are -// compiled. -// -// This class uses the Clang Tooling infrastructure, see -// http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html -// for details on setting it up with LLVM source tree. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMANDLINECLANGTOOL_H -#define LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMANDLINECLANGTOOL_H - -#include "llvm/Support/CommandLine.h" -#include "clang/Tooling/CompilationDatabase.h" - -namespace clang { - -namespace tooling { - -class CompilationDatabase; -class FrontendActionFactory; - -/// \brief A common driver for command-line Clang tools. -/// -/// Parses a common subset of command-line arguments, locates and loads a -/// compilation commands database, runs a tool with user-specified action. It -/// also contains a help message for the common command-line options. -/// An example of usage: -/// @code -/// int main(int argc, const char **argv) { -/// CommandLineClangTool Tool; -/// cl::extrahelp MoreHelp("\nMore help text..."); -/// Tool.initialize(argc, argv); -/// return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>()); -/// } -/// @endcode -/// -class CommandLineClangTool { -public: - /// Sets up command-line options and help messages. - /// Add your own help messages after constructing this tool. - CommandLineClangTool(); - - /// Parses command-line, initializes a compilation database. - /// This method exits program in case of error. - void initialize(int argc, const char **argv); - - /// Runs a clang tool with an action created by \c ActionFactory. - int run(FrontendActionFactory *ActionFactory); - -private: - llvm::OwningPtr<CompilationDatabase> Compilations; - llvm::cl::opt<std::string> BuildPath; - llvm::cl::list<std::string> SourcePaths; - llvm::cl::extrahelp MoreHelp; -}; - -} // namespace tooling - -} // namespace clang - -#endif // LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMANDLINECLANGTOOL_H diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h b/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h new file mode 100644 index 0000000..a1bad12 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h @@ -0,0 +1,89 @@ +//===- CommonOptionsParser.h - common options for clang tools -*- C++ -*-=====// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the CommonOptionsParser class used to parse common +// command-line options for clang tools, so that they can be run as separate +// command-line applications with a consistent common interface for handling +// compilation database and input files. +// +// It provides a common subset of command-line options, common algorithm +// for locating a compilation database and source files, and help messages +// for the basic command-line interface. +// +// It creates a CompilationDatabase and reads common command-line options. +// +// This class uses the Clang Tooling infrastructure, see +// http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html +// for details on setting it up with LLVM source tree. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H +#define LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H + +#include "clang/Tooling/CompilationDatabase.h" + +namespace clang { +namespace tooling { +/// \brief A parser for options common to all command-line Clang tools. +/// +/// Parses a common subset of command-line arguments, locates and loads a +/// compilation commands database and runs a tool with user-specified action. It +/// also contains a help message for the common command-line options. +/// +/// An example of usage: +/// \code +/// #include "clang/Frontend/FrontendActions.h" +/// #include "clang/Tooling/CommonOptionsParser.h" +/// #include "llvm/Support/CommandLine.h" +/// +/// using namespace clang::tooling; +/// using namespace llvm; +/// +/// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); +/// static cl::extrahelp MoreHelp("\nMore help text..."); +/// static cl:opt<bool> YourOwnOption(...); +/// ... +/// +/// int main(int argc, const char **argv) { +/// CommonOptionsParser OptionsParser(argc, argv); +/// ClangTool Tool(OptionsParser.GetCompilations(), +/// OptionsParser.GetSourcePathListi()); +/// return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>()); +/// } +/// \endcode +class CommonOptionsParser { +public: + /// \brief Parses command-line, initializes a compilation database. + /// This constructor can change argc and argv contents, e.g. consume + /// command-line options used for creating FixedCompilationDatabase. + /// This constructor exits program in case of error. + CommonOptionsParser(int &argc, const char **argv); + + /// Returns a reference to the loaded compilations database. + CompilationDatabase &GetCompilations() { + return *Compilations; + } + + /// Returns a list of source file paths to process. + std::vector<std::string> GetSourcePathList() { + return SourcePathList; + } + + static const char *const HelpMessage; + +private: + llvm::OwningPtr<CompilationDatabase> Compilations; + std::vector<std::string> SourcePathList; +}; + +} // namespace tooling +} // namespace clang + +#endif // LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h index f78ffae..a40bffe 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h @@ -31,12 +31,9 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/YAMLParser.h" + #include <string> #include <vector> @@ -111,6 +108,27 @@ public: virtual std::vector<std::string> getAllFiles() const = 0; }; +/// \brief Interface for compilation database plugins. +/// +/// A compilation database plugin allows the user to register custom compilation +/// databases that are picked up as compilation database if the corresponding +/// library is linked in. To register a plugin, declare a static variable like: +/// +/// \code +/// static CompilationDatabasePluginRegistry::Add<MyDatabasePlugin> +/// X("my-compilation-database", "Reads my own compilation database"); +/// \endcode +class CompilationDatabasePlugin { +public: + virtual ~CompilationDatabasePlugin(); + + /// \brief Loads a compilation database from a build directory. + /// + /// \see CompilationDatabase::loadFromDirectory(). + virtual CompilationDatabase *loadFromDirectory(StringRef Directory, + std::string &ErrorMessage) = 0; +}; + /// \brief A compilation database that returns a single compile command line. /// /// Useful when we want a tool to behave more like a compiler invocation. @@ -169,75 +187,6 @@ private: std::vector<CompileCommand> CompileCommands; }; -/// \brief A JSON based compilation database. -/// -/// JSON compilation database files must contain a list of JSON objects which -/// provide the command lines in the attributes 'directory', 'command' and -/// 'file': -/// [ -/// { "directory": "<working directory of the compile>", -/// "command": "<compile command line>", -/// "file": "<path to source file>" -/// }, -/// ... -/// ] -/// Each object entry defines one compile action. The specified file is -/// considered to be the main source file for the translation unit. -/// -/// JSON compilation databases can for example be generated in CMake projects -/// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS. -class JSONCompilationDatabase : public CompilationDatabase { -public: - /// \brief Loads a JSON compilation database from the specified file. - /// - /// Returns NULL and sets ErrorMessage if the database could not be - /// loaded from the given file. - static JSONCompilationDatabase *loadFromFile(StringRef FilePath, - std::string &ErrorMessage); - - /// \brief Loads a JSON compilation database from a data buffer. - /// - /// Returns NULL and sets ErrorMessage if the database could not be loaded. - static JSONCompilationDatabase *loadFromBuffer(StringRef DatabaseString, - std::string &ErrorMessage); - - /// \brief Returns all compile comamnds in which the specified file was - /// compiled. - /// - /// FIXME: Currently FilePath must be an absolute path inside the - /// source directory which does not have symlinks resolved. - virtual std::vector<CompileCommand> getCompileCommands( - StringRef FilePath) const; - - /// \brief Returns the list of all files available in the compilation database. - /// - /// These are the 'file' entries of the JSON objects. - virtual std::vector<std::string> getAllFiles() const; - -private: - /// \brief Constructs a JSON compilation database on a memory buffer. - JSONCompilationDatabase(llvm::MemoryBuffer *Database) - : Database(Database), YAMLStream(Database->getBuffer(), SM) {} - - /// \brief Parses the database file and creates the index. - /// - /// Returns whether parsing succeeded. Sets ErrorMessage if parsing - /// failed. - bool parse(std::string &ErrorMessage); - - // Tuple (directory, commandline) where 'commandline' pointing to the - // corresponding nodes in the YAML stream. - typedef std::pair<llvm::yaml::ScalarNode*, - llvm::yaml::ScalarNode*> CompileCommandRef; - - // Maps file paths to the compile command lines for that file. - llvm::StringMap< std::vector<CompileCommandRef> > IndexByFile; - - llvm::OwningPtr<llvm::MemoryBuffer> Database; - llvm::SourceMgr SM; - llvm::yaml::Stream YAMLStream; -}; - } // end namespace tooling } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h new file mode 100644 index 0000000..84fcd24 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h @@ -0,0 +1,27 @@ +//===--- CompilationDatabasePluginRegistry.h - ------------------*- 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_TOOLING_COMPILATION_DATABASE_PLUGIN_REGISTRY_H +#define LLVM_CLANG_TOOLING_COMPILATION_DATABASE_PLUGIN_REGISTRY_H + +#include "clang/Tooling/CompilationDatabase.h" +#include "llvm/Support/Registry.h" + +namespace clang { +namespace tooling { + +class CompilationDatabasePlugin; + +typedef llvm::Registry<CompilationDatabasePlugin> + CompilationDatabasePluginRegistry; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_COMPILATION_DATABASE_PLUGIN_REGISTRY_H diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/FileMatchTrie.h b/contrib/llvm/tools/clang/include/clang/Tooling/FileMatchTrie.h new file mode 100644 index 0000000..ff988be --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Tooling/FileMatchTrie.h @@ -0,0 +1,90 @@ +//===--- FileMatchTrie.h - --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a match trie to find the matching file in a compilation +// database based on a given path in the presence of symlinks. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H +#define LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/StringRef.h" + +#include <string> +#include <vector> + +namespace clang { +namespace tooling { + +struct PathComparator { + virtual ~PathComparator() {} + virtual bool equivalent(StringRef FileA, StringRef FileB) const = 0; +}; +class FileMatchTrieNode; + +/// \brief A trie to efficiently match against the entries of the compilation +/// database in order of matching suffix length. +/// +/// When a clang tool is supposed to operate on a specific file, we have to +/// find the corresponding file in the compilation database. Although entries +/// in the compilation database are keyed by filename, a simple string match +/// is insufficient because of symlinks. Commonly, a project hierarchy looks +/// like this: +/// /<project-root>/src/<path>/<somefile>.cc (used as input for the tool) +/// /<project-root>/build/<symlink-to-src>/<path>/<somefile>.cc (stored in DB) +/// +/// Furthermore, there might be symlinks inside the source folder or inside the +/// database, so that the same source file is translated with different build +/// options. +/// +/// For a given input file, the \c FileMatchTrie finds its entries in order +/// of matching suffix length. For each suffix length, there might be one or +/// more entries in the database. For each of those entries, it calls +/// \c llvm::sys::fs::equivalent() (injected as \c PathComparator). There might +/// be zero or more entries with the same matching suffix length that are +/// equivalent to the input file. Three cases are distinguished: +/// 0 equivalent files: Continue with the next suffix length. +/// 1 equivalent file: Best match found, return it. +/// >1 equivalent files: Match is ambiguous, return error. +class FileMatchTrie { +public: + FileMatchTrie(); + + /// \brief Construct a new \c FileMatchTrie with the given \c PathComparator. + /// + /// The \c FileMatchTrie takes ownership of 'Comparator'. Used for testing. + FileMatchTrie(PathComparator* Comparator); + + ~FileMatchTrie(); + + /// \brief Insert a new absolute path. Relative paths are ignored. + void insert(StringRef NewPath); + + /// \brief Finds the corresponding file in this trie. + /// + /// Returns file name stored in this trie that is equivalent to 'FileName' + /// according to 'Comparator', if it can be uniquely identified. If there + /// are no matches an empty \c StringRef is returned. If there are ambigious + /// matches, an empty \c StringRef is returned and a corresponding message + /// written to 'Error'. + StringRef findEquivalent(StringRef FileName, + llvm::raw_ostream &Error) const; +private: + FileMatchTrieNode *Root; + OwningPtr<PathComparator> Comparator; +}; + + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h b/contrib/llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h new file mode 100644 index 0000000..d62ab5c --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h @@ -0,0 +1,107 @@ +//===--- JSONCompilationDatabase.h - ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The JSONCompilationDatabase finds compilation databases supplied as a file +// 'compile_commands.json'. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_JSON_COMPILATION_DATABASE_H +#define LLVM_CLANG_TOOLING_JSON_COMPILATION_DATABASE_H + +#include "clang/Basic/LLVM.h" +#include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/FileMatchTrie.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/YAMLParser.h" +#include <string> +#include <vector> + +namespace clang { +namespace tooling { + +/// \brief A JSON based compilation database. +/// +/// JSON compilation database files must contain a list of JSON objects which +/// provide the command lines in the attributes 'directory', 'command' and +/// 'file': +/// [ +/// { "directory": "<working directory of the compile>", +/// "command": "<compile command line>", +/// "file": "<path to source file>" +/// }, +/// ... +/// ] +/// Each object entry defines one compile action. The specified file is +/// considered to be the main source file for the translation unit. +/// +/// JSON compilation databases can for example be generated in CMake projects +/// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS. +class JSONCompilationDatabase : public CompilationDatabase { +public: + /// \brief Loads a JSON compilation database from the specified file. + /// + /// Returns NULL and sets ErrorMessage if the database could not be + /// loaded from the given file. + static JSONCompilationDatabase *loadFromFile(StringRef FilePath, + std::string &ErrorMessage); + + /// \brief Loads a JSON compilation database from a data buffer. + /// + /// Returns NULL and sets ErrorMessage if the database could not be loaded. + static JSONCompilationDatabase *loadFromBuffer(StringRef DatabaseString, + std::string &ErrorMessage); + + /// \brief Returns all compile comamnds in which the specified file was + /// compiled. + /// + /// FIXME: Currently FilePath must be an absolute path inside the + /// source directory which does not have symlinks resolved. + virtual std::vector<CompileCommand> getCompileCommands( + StringRef FilePath) const; + + /// \brief Returns the list of all files available in the compilation database. + /// + /// These are the 'file' entries of the JSON objects. + virtual std::vector<std::string> getAllFiles() const; + +private: + /// \brief Constructs a JSON compilation database on a memory buffer. + JSONCompilationDatabase(llvm::MemoryBuffer *Database) + : Database(Database), YAMLStream(Database->getBuffer(), SM) {} + + /// \brief Parses the database file and creates the index. + /// + /// Returns whether parsing succeeded. Sets ErrorMessage if parsing + /// failed. + bool parse(std::string &ErrorMessage); + + // Tuple (directory, commandline) where 'commandline' pointing to the + // corresponding nodes in the YAML stream. + typedef std::pair<llvm::yaml::ScalarNode*, + llvm::yaml::ScalarNode*> CompileCommandRef; + + // Maps file paths to the compile command lines for that file. + llvm::StringMap< std::vector<CompileCommandRef> > IndexByFile; + + FileMatchTrie MatchTrie; + + llvm::OwningPtr<llvm::MemoryBuffer> Database; + llvm::SourceMgr SM; + llvm::yaml::Stream YAMLStream; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_JSON_COMPILATION_DATABASE_H diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/Refactoring.h b/contrib/llvm/tools/clang/include/clang/Tooling/Refactoring.h index 0e42a0e..aaffc1a 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/Refactoring.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/Refactoring.h @@ -74,6 +74,7 @@ public: StringRef getFilePath() const { return FilePath; } unsigned getOffset() const { return Offset; } unsigned getLength() const { return Length; } + StringRef getReplacementText() const { return ReplacementText; } /// @} /// \brief Applies the replacement on the Rewriter. diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h b/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h index e06705f..a03bcb1 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h @@ -74,6 +74,14 @@ public: template <typename T> FrontendActionFactory *newFrontendActionFactory(); +/// \brief Called at the end of each source file when used with +/// \c newFrontendActionFactory. +class EndOfSourceFileCallback { +public: + virtual ~EndOfSourceFileCallback() {} + virtual void run() = 0; +}; + /// \brief Returns a new FrontendActionFactory for any type that provides an /// implementation of newASTConsumer(). /// @@ -87,7 +95,7 @@ FrontendActionFactory *newFrontendActionFactory(); /// newFrontendActionFactory(&Factory); template <typename FactoryT> inline FrontendActionFactory *newFrontendActionFactory( - FactoryT *ConsumerFactory); + FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback = NULL); /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. /// @@ -99,6 +107,19 @@ inline FrontendActionFactory *newFrontendActionFactory( bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, const Twine &FileName = "input.cc"); +/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and +/// with additional other flags. +/// +/// \param ToolAction The action to run over the code. +/// \param Code C++ code. +/// \param Args Additional flags to pass on. +/// \param FileName The file name which 'Code' will be mapped as. +/// +/// \return - True if 'ToolAction' was successfully executed. +bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code, + const std::vector<std::string> &Args, + const Twine &FileName = "input.cc"); + /// \brief Utility to run a FrontendAction in a single clang invocation. class ToolInvocation { public: @@ -204,34 +225,45 @@ FrontendActionFactory *newFrontendActionFactory() { template <typename FactoryT> inline FrontendActionFactory *newFrontendActionFactory( - FactoryT *ConsumerFactory) { + FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback) { class FrontendActionFactoryAdapter : public FrontendActionFactory { public: - explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory) - : ConsumerFactory(ConsumerFactory) {} + explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory, + EndOfSourceFileCallback *EndCallback) + : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {} virtual clang::FrontendAction *create() { - return new ConsumerFactoryAdaptor(ConsumerFactory); + return new ConsumerFactoryAdaptor(ConsumerFactory, EndCallback); } private: class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { public: - ConsumerFactoryAdaptor(FactoryT *ConsumerFactory) - : ConsumerFactory(ConsumerFactory) {} + ConsumerFactoryAdaptor(FactoryT *ConsumerFactory, + EndOfSourceFileCallback *EndCallback) + : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {} clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &, llvm::StringRef) { return ConsumerFactory->newASTConsumer(); } + protected: + virtual void EndSourceFileAction() { + if (EndCallback != NULL) + EndCallback->run(); + clang::ASTFrontendAction::EndSourceFileAction(); + } + private: FactoryT *ConsumerFactory; + EndOfSourceFileCallback *EndCallback; }; FactoryT *ConsumerFactory; + EndOfSourceFileCallback *EndCallback; }; - return new FrontendActionFactoryAdapter(ConsumerFactory); + return new FrontendActionFactoryAdapter(ConsumerFactory, EndCallback); } /// \brief Returns the absolute path of \c File, by prepending it with |