diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include')
264 files changed, 16446 insertions, 6829 deletions
diff --git a/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h b/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h index ff1ec63..fd65418 100644 --- a/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h +++ b/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h @@ -58,7 +58,7 @@ typedef void * CXCompileCommand; */ typedef enum { /* - * \brief No error occured + * \brief No error occurred */ CXCompilationDatabase_NoError = 0, @@ -142,6 +142,24 @@ CINDEX_LINKAGE CXString clang_CompileCommand_getArg(CXCompileCommand, unsigned I); /** + * \brief Get the number of source mappings for the compiler invocation. + */ +CINDEX_LINKAGE unsigned +clang_CompileCommand_getNumMappedSources(CXCompileCommand); + +/** + * \brief Get the I'th mapped source path for the compiler invocation. + */ +CINDEX_LINKAGE CXString +clang_CompileCommand_getMappedSourcePath(CXCompileCommand, unsigned I); + +/** + * \brief Get the I'th mapped source content for the compiler invocation. + */ +CINDEX_LINKAGE CXString +clang_CompileCommand_getMappedSourceContent(CXCompileCommand, unsigned I); + +/** * @} */ diff --git a/contrib/llvm/tools/clang/include/clang-c/CXString.h b/contrib/llvm/tools/clang/include/clang-c/CXString.h index 34cab5e..592c4dc 100644 --- a/contrib/llvm/tools/clang/include/clang-c/CXString.h +++ b/contrib/llvm/tools/clang/include/clang-c/CXString.h @@ -46,7 +46,7 @@ typedef struct { CINDEX_LINKAGE const char *clang_getCString(CXString string); /** - * \brief Free the given string, + * \brief Free the given string. */ CINDEX_LINKAGE void clang_disposeString(CXString string); diff --git a/contrib/llvm/tools/clang/include/clang-c/Index.h b/contrib/llvm/tools/clang/include/clang-c/Index.h index 4d08e3b..95d54c2 100644 --- a/contrib/llvm/tools/clang/include/clang-c/Index.h +++ b/contrib/llvm/tools/clang/include/clang-c/Index.h @@ -16,9 +16,7 @@ #ifndef CLANG_C_INDEX_H #define CLANG_C_INDEX_H -#include <sys/stat.h> #include <time.h> -#include <stdio.h> #include "clang-c/Platform.h" #include "clang-c/CXString.h" @@ -32,7 +30,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 19 +#define CINDEX_VERSION_MINOR 20 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -414,6 +412,12 @@ CINDEX_LINKAGE CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu, CINDEX_LINKAGE int clang_Location_isInSystemHeader(CXSourceLocation location); /** + * \brief Returns non-zero if the given source location is in the main file of + * the corresponding translation unit. + */ +CINDEX_LINKAGE int clang_Location_isFromMainFile(CXSourceLocation location); + +/** * \brief Retrieve a NULL (invalid) source range. */ CINDEX_LINKAGE CXSourceRange clang_getNullRange(void); @@ -723,7 +727,7 @@ CINDEX_LINKAGE void clang_disposeDiagnosticSet(CXDiagnosticSet Diags); * \brief Retrieve the child diagnostics of a CXDiagnostic. * * This CXDiagnosticSet does not need to be released by - * clang_diposeDiagnosticSet. + * clang_disposeDiagnosticSet. */ CINDEX_LINKAGE CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D); @@ -763,7 +767,7 @@ CINDEX_LINKAGE void clang_disposeDiagnostic(CXDiagnostic Diagnostic); * \brief Options to control the display of diagnostics. * * The values in this enum are meant to be combined to customize the - * behavior of \c clang_displayDiagnostic(). + * behavior of \c clang_formatDiagnostic(). */ enum CXDiagnosticDisplayOptions { /** @@ -850,7 +854,7 @@ CINDEX_LINKAGE CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, * default behavior of the clang compiler. * * \returns A set of display options suitable for use with \c - * clang_displayDiagnostic(). + * clang_formatDiagnostic(). */ CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void); @@ -1942,7 +1946,7 @@ enum CXCursorKind { */ CXCursor_CompoundStmt = 202, - /** \brief A case statment. + /** \brief A case statement. */ CXCursor_CaseStmt = 203, @@ -2062,7 +2066,11 @@ enum CXCursorKind { */ CXCursor_DeclStmt = 231, - CXCursor_LastStmt = CXCursor_DeclStmt, + /** \brief OpenMP parallel directive. + */ + CXCursor_OMPParallelDirective = 232, + + CXCursor_LastStmt = CXCursor_OMPParallelDirective, /** * \brief Cursor that represents the translation unit itself. @@ -2087,7 +2095,8 @@ enum CXCursorKind { CXCursor_CXXOverrideAttr = 405, CXCursor_AnnotateAttr = 406, CXCursor_AsmLabelAttr = 407, - CXCursor_LastAttr = CXCursor_AsmLabelAttr, + CXCursor_PackedAttr = 408, + CXCursor_LastAttr = CXCursor_PackedAttr, /* Preprocessing */ CXCursor_PreprocessingDirective = 500, @@ -2666,7 +2675,11 @@ enum CXTypeKind { CXType_FunctionNoProto = 110, CXType_FunctionProto = 111, CXType_ConstantArray = 112, - CXType_Vector = 113 + CXType_Vector = 113, + CXType_IncompleteArray = 114, + CXType_VariableArray = 115, + CXType_DependentSizedArray = 116, + CXType_MemberPointer = 117 }; /** @@ -2957,6 +2970,13 @@ enum CXTypeLayoutError { CINDEX_LINKAGE long long clang_Type_getAlignOf(CXType T); /** + * \brief Return the class type of an member pointer type. + * + * If a non-member-pointer type is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getClassType(CXType T); + +/** * \brief Return the size of a type in bytes as per C++[expr.sizeof] standard. * * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned. @@ -2982,6 +3002,23 @@ CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T); */ CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S); +enum CXRefQualifierKind { + /** \brief No ref-qualifier was provided. */ + CXRefQualifier_None = 0, + /** \brief An lvalue ref-qualifier was provided (\c &). */ + CXRefQualifier_LValue, + /** \brief An rvalue ref-qualifier was provided (\c &&). */ + CXRefQualifier_RValue +}; + +/** + * \brief Retrieve the ref-qualifier kind of a function or method. + * + * The ref-qualifier is returned for C++ functions or methods. For other types + * or non-C++ declarations, CXRefQualifier_None is returned. + */ +CINDEX_LINKAGE enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T); + /** * \brief Returns non-zero if the cursor specifies a Record member that is a * bitfield. @@ -3416,6 +3453,13 @@ typedef enum { CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C); /** + * \brief Given a cursor that represents an ObjC method or property declaration, + * return non-zero if the declaration was affected by "@optional". + * Returns zero if the cursor is not such a declaration or it is "@required". + */ +CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C); + +/** * \brief Returns non-zero if the given cursor is a variadic function or method. */ CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C); @@ -4037,6 +4081,12 @@ CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment); */ /** + * \brief Determine if a C++ member function or member function template is + * pure virtual. + */ +CINDEX_LINKAGE unsigned clang_CXXMethod_isPureVirtual(CXCursor C); + +/** * \brief Determine if a C++ member function or member function template is * declared 'static'. */ diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h index c167d3c..196f6c0 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMT.h @@ -97,6 +97,8 @@ class MigrationProcess { FileRemapper Remapper; public: + bool HadARCErrors; + MigrationProcess(const CompilerInvocation &CI, DiagnosticConsumer *diagClient, StringRef outputDir = StringRef()); diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h index 2daaf73..45c8b4e 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/ARCMTActions.h @@ -57,14 +57,12 @@ public: /// \brief Migrates to modern ObjC syntax. class ObjCMigrateAction : public WrapperFrontendAction { std::string MigrateDir; - bool MigrateLiterals; - bool MigrateSubscripting; + unsigned ObjCMigAction; FileRemapper Remapper; CompilerInstance *CompInst; public: ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, - bool migrateLiterals, - bool migrateSubscripting); + unsigned migrateAction); protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile); diff --git a/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h b/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h index 94c9e8f..f7677cc 100644 --- a/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h +++ b/contrib/llvm/tools/clang/include/clang/ARCMigrate/FileRemapper.h @@ -53,7 +53,6 @@ public: StringRef outputDir = StringRef()); void remap(StringRef filePath, llvm::MemoryBuffer *memBuf); - void remap(StringRef filePath, StringRef newPath); void applyMappings(PreprocessorOptions &PPOpts) const; diff --git a/contrib/llvm/tools/clang/include/clang/AST/APValue.h b/contrib/llvm/tools/clang/include/clang/AST/APValue.h index ec8faa4..b4fd2af 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/APValue.h +++ b/contrib/llvm/tools/clang/include/clang/AST/APValue.h @@ -168,6 +168,13 @@ public: MakeUninit(); } + /// \brief Returns whether the object performed allocations. + /// + /// If APValues are constructed via placement new, \c needsCleanup() + /// indicates whether the destructor must be called in order to correctly + /// free all allocated memory. + bool needsCleanup() const; + /// \brief Swaps the contents of this and the given APValue. void swap(APValue &RHS); diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h b/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h index ae77943..7b6fa94 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTConsumer.h @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_AST_ASTCONSUMER_H #define LLVM_CLANG_AST_ASTCONSUMER_H +#include "llvm/ADT/StringRef.h" + namespace clang { class ASTContext; class CXXRecordDecl; @@ -70,6 +72,10 @@ public: /// can be defined in declspecs). virtual void HandleTagDeclDefinition(TagDecl *D) {} + /// \brief This callback is invoked the first time each TagDecl is required to + /// be complete. + virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {} + /// \brief Invoked when a function is implicitly instantiated. /// Note that at this point point it does not have a body, its body is /// instantiated at the end of the translation unit and passed to @@ -86,6 +92,21 @@ public: /// The default implementation passes it to HandleTopLevelDecl. virtual void HandleImplicitImportDecl(ImportDecl *D); + /// \brief Handle a pragma that appends to Linker Options. Currently this + /// only exists to support Microsoft's #pragma comment(linker, "/foo"). + virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {} + + /// \brief Handle a pragma that emits a mismatch identifier and value to the + /// object file for the linker to work with. Currently, this only exists to + /// support Microsoft's #pragma detect_mismatch. + virtual void HandleDetectMismatch(llvm::StringRef Name, + llvm::StringRef Value) {} + + /// \brief Handle a dependent library created by a pragma in the source. + /// Currently this only exists to support Microsoft's + /// #pragma comment(lib, "/foo"). + virtual void HandleDependentLibrary(llvm::StringRef Lib) {} + /// CompleteTentativeDefinition - Callback invoked at the end of a translation /// unit to notify the consumer that the given tentative definition should be /// completed. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h index c5d3337..f420e85 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h @@ -19,11 +19,9 @@ #include "clang/AST/CanonicalType.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/Decl.h" -#include "clang/AST/LambdaMangleContext.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/RawCommentList.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/Basic/AddressSpaces.h" @@ -47,6 +45,7 @@ namespace llvm { namespace clang { class FileManager; + class AtomicExpr; class ASTRecordLayout; class BlockExpr; class CharUnits; @@ -55,9 +54,11 @@ namespace clang { class ExternalASTSource; class ASTMutationListener; class IdentifierTable; + class MaterializeTemporaryExpr; class SelectorTable; class TargetInfo; class CXXABI; + class MangleNumberingContext; // Decls class MangleContext; class ObjCIvarDecl; @@ -81,6 +82,7 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable llvm::FoldingSet<ExtQuals> ExtQualNodes; mutable llvm::FoldingSet<ComplexType> ComplexTypes; mutable llvm::FoldingSet<PointerType> PointerTypes; + mutable llvm::FoldingSet<DecayedType> DecayedTypes; mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes; mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes; mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes; @@ -146,7 +148,7 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable TypeInfoMap MemoizedTypeInfo; /// \brief A cache mapping from CXXRecordDecls to key functions. - llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions; + llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions; /// \brief Mapping from ObjCContainers to their ObjCImplementations. llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls; @@ -163,6 +165,11 @@ class ASTContext : public RefCountedBase<ASTContext> { llvm::DenseMap<const FunctionDecl*, FunctionDecl*> ClassScopeSpecializationPattern; + /// \brief Mapping from materialized temporaries with static storage duration + /// that appear in constant initializers to their evaluated values. + llvm::DenseMap<const MaterializeTemporaryExpr*, APValue> + MaterializedTemporaryValues; + /// \brief Representation of a "canonical" template template parameter that /// is used in canonical template names. class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode { @@ -190,6 +197,9 @@ class ASTContext : public RefCountedBase<ASTContext> { /// \brief The typedef for the __uint128_t type. mutable TypedefDecl *UInt128Decl; + + /// \brief The typedef for the __float128 stub type. + mutable TypeDecl *Float128StubDecl; /// \brief The typedef for the target specific predefined /// __builtin_va_list type. @@ -261,13 +271,30 @@ class ASTContext : public RefCountedBase<ASTContext> { /// wasting space in the Decl class. llvm::DenseMap<const Decl*, AttrVec*> DeclAttrs; - /// \brief Keeps track of the static data member templates from which - /// static data members of class template specializations were instantiated. + /// \brief A mapping from non-redeclarable declarations in modules that were + /// merged with other declarations to the canonical declaration that they were + /// merged into. + llvm::DenseMap<Decl*, Decl*> MergedDecls; + +public: + /// \brief A type synonym for the TemplateOrInstantiation mapping. + typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *> + TemplateOrSpecializationInfo; + +private: + + /// \brief A mapping to contain the template or declaration that + /// a variable declaration describes or was instantiated from, + /// respectively. /// - /// This data structure stores the mapping from instantiations of static - /// data members to the static data member representations within the - /// class template from which they were instantiated along with the kind - /// of instantiation or specialization (a TemplateSpecializationKind - 1). + /// For non-templates, this value will be NULL. For variable + /// declarations that describe a variable template, this will be a + /// pointer to a VarTemplateDecl. For static data members + /// of class template specializations, this will be the + /// MemberSpecializationInfo referring to the member variable that was + /// instantiated or specialized. Thus, the mapping will keep track of + /// the static data member templates from which static data members of + /// class template specializations were instantiated. /// /// Given the following example: /// @@ -286,8 +313,8 @@ class ASTContext : public RefCountedBase<ASTContext> { /// This mapping will contain an entry that maps from the VarDecl for /// X<int>::value to the corresponding VarDecl for X<T>::value (within the /// class template X) and will be marked TSK_ImplicitInstantiation. - llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *> - InstantiatedFromStaticDataMember; + llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo> + TemplateOrInstantiation; /// \brief Keeps track of the declaration from which a UsingDecl was /// created during instantiation. @@ -328,12 +355,15 @@ class ASTContext : public RefCountedBase<ASTContext> { typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector; llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods; - /// \brief Mapping from each declaration context to its corresponding lambda - /// mangling context. - llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts; + /// \brief Mapping from each declaration context to its corresponding + /// mangling numbering context (used for constructs like lambdas which + /// need to be consistently numbered for the mangler). + llvm::DenseMap<const DeclContext *, MangleNumberingContext *> + MangleNumberingContexts; - llvm::DenseMap<const DeclContext *, unsigned> UnnamedMangleContexts; - llvm::DenseMap<const TagDecl *, unsigned> UnnamedMangleNumbers; + /// \brief Side-table of mangling numbers for declarations which rarely + /// need them (like static local vars). + llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers; /// \brief Mapping that stores parameterIndex values for ParmVarDecls when /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex. @@ -368,6 +398,10 @@ class ASTContext : public RefCountedBase<ASTContext> { /// \brief The logical -> physical address space map. const LangAS::Map *AddrSpaceMap; + /// \brief Address space map mangling must be used with language specific + /// address spaces (e.g. OpenCL/CUDA) + bool AddrSpaceMapMangling; + friend class ASTDeclReader; friend class ASTReader; friend class ASTWriter; @@ -419,22 +453,7 @@ public: return getParents(ast_type_traits::DynTypedNode::create(Node)); } - ParentVector getParents(const ast_type_traits::DynTypedNode &Node) { - assert(Node.getMemoizationData() && - "Invariant broken: only nodes that support memoization may be " - "used in the parent map."); - if (!AllParents) { - // We always need to run over the whole translation unit, as - // hasAncestor can escape any subtree. - AllParents.reset( - ParentMapASTVisitor::buildMap(*getTranslationUnitDecl())); - } - ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData()); - if (I == AllParents->end()) { - return ParentVector(); - } - return I->second; - } + ParentVector getParents(const ast_type_traits::DynTypedNode &Node); const clang::PrintingPolicy &getPrintingPolicy() const { return PrintingPolicy; @@ -451,7 +470,7 @@ public: return BumpAlloc; } - void *Allocate(unsigned Size, unsigned Align = 8) const { + void *Allocate(size_t Size, unsigned Align = 8) const { return BumpAlloc.Allocate(Size, Align); } void Deallocate(void *Ptr) const { } @@ -470,6 +489,19 @@ public: const TargetInfo &getTargetInfo() const { return *Target; } + /// getIntTypeForBitwidth - + /// sets integer QualTy according to specified details: + /// bitwidth, signed/unsigned. + /// Returns empty type if there is no appropriate target types. + QualType getIntTypeForBitwidth(unsigned DestWidth, + unsigned Signed) const; + /// getRealTypeForBitwidth - + /// sets floating point QualTy according to specified bitwidth. + /// Returns empty type if there is no appropriate target types. + QualType getRealTypeForBitwidth(unsigned DestWidth) const; + + bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const; + const LangOptions& getLangOpts() const { return LangOpts; } DiagnosticsEngine &getDiagnostics() const; @@ -580,7 +612,12 @@ public: /// preprocessor is not available. comments::FullComment *getCommentForDecl(const Decl *D, const Preprocessor *PP) const; - + + /// Return parsed documentation comment attached to a given declaration. + /// Returns NULL if no comment is attached. Does not look at any + /// redeclarations of the declaration. + comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const; + comments::FullComment *cloneFullComment(comments::FullComment *FC, const Decl *D) const; @@ -601,9 +638,13 @@ public: /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. + // FIXME: Remove ? MemberSpecializationInfo *getInstantiatedFromStaticDataMember( const VarDecl *Var); + TemplateOrSpecializationInfo + getTemplateOrSpecializationInfo(const VarDecl *Var); + FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD); void setClassScopeSpecializationPattern(FunctionDecl *FD, @@ -615,6 +656,9 @@ public: TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation = SourceLocation()); + void setTemplateOrSpecializationInfo(VarDecl *Inst, + TemplateOrSpecializationInfo TSI); + /// \brief If the given using decl \p Inst is an instantiation of a /// (possibly unresolved) using decl from a template instantiation, /// return it. @@ -632,31 +676,6 @@ public: void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl); - /// \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; - - /// \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; - - /// \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; - - /// \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; - - /// \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; - // Access to the set of methods overridden by the given C++ method. typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator; overridden_cxx_method_iterator @@ -732,7 +751,15 @@ public: return import_iterator(FirstLocalImport); } import_iterator local_import_end() const { return import_iterator(); } - + + Decl *getPrimaryMergedDecl(Decl *D) { + Decl *Result = MergedDecls.lookup(D); + return Result ? Result : D; + } + void setPrimaryMergedDecl(Decl *D, Decl *Primary) { + MergedDecls[D] = Primary; + } + TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } @@ -740,7 +767,8 @@ public: CanQualType VoidTy; CanQualType BoolTy; CanQualType CharTy; - CanQualType WCharTy; // [C++ 3.9.1p5], integer type in C99. + CanQualType WCharTy; // [C++ 3.9.1p5]. + CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99. CanQualType WIntTy; // [C99 7.24.1], integer type unchanged by default promotions. CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99. CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99. @@ -809,6 +837,9 @@ public: /// \brief Retrieve the declaration for the 128-bit unsigned integer type. TypedefDecl *getUInt128Decl() const; + + /// \brief Retrieve the declaration for a 128-bit float stub type. + TypeDecl *getFloat128StubType() const; //===--------------------------------------------------------------------===// // Type Constructors @@ -884,6 +915,14 @@ public: return CanQualType::CreateUnsafe(getPointerType((QualType) T)); } + /// \brief Return the uniqued reference to the decayed version of the given + /// type. Can only be called on array and function types which decay to + /// pointer types. + QualType getDecayedType(QualType T) const; + CanQualType getDecayedType(CanQualType T) const { + return CanQualType::CreateUnsafe(getDecayedType((QualType) T)); + } + /// \brief Return the uniqued reference to the atomic type for the specified /// type. QualType getAtomicType(QualType T) const; @@ -1104,7 +1143,7 @@ public: /// \brief C++11 deduced auto type. QualType getAutoType(QualType DeducedType, bool IsDecltypeAuto, - bool IsDependent = false) const; + bool IsDependent) const; /// \brief C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; @@ -1130,11 +1169,15 @@ public: /// <stdint.h>. CanQualType getUIntMaxType() const; - /// \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. + /// \brief Return the unique wchar_t type available in C++ (and available as + /// __wchar_t as a Microsoft extension). QualType getWCharType() const { return WCharTy; } + /// \brief Return the type of wide characters. 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 getWideCharType() const { return WideCharTy; } + /// \brief Return the type of "signed wchar_t". /// /// Used when in C++, as a GCC extension. @@ -1607,14 +1650,17 @@ public: /// \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; + /// If \p ForAlignof, references are treated like their underlying type + /// and large arrays don't get any special treatment. If not \p ForAlignof + /// it computes the value expected by CodeGen: references are treated like + /// pointers and large arrays get extra alignment. + CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const; /// \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; + const ASTRecordLayout *BuildMicrosoftASTRecordLayout(const RecordDecl *D) const; /// \brief Get or compute information about the layout of the specified /// Objective-C interface. @@ -1721,6 +1767,9 @@ public: getCanonicalType(T2).getTypePtr(); } + bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, + const ObjCMethodDecl *MethodImp); + bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2); /// \brief Retrieves the "canonical" nested name specifier for a @@ -1749,19 +1798,9 @@ public: NestedNameSpecifier * getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const; - /// \brief Retrieves the default calling convention to use for - /// C++ instance methods. - CallingConv getDefaultCXXMethodCallConv(bool isVariadic); - - /// \brief Retrieves the canonical representation of the given - /// calling convention. - CallingConv getCanonicalCallConv(CallingConv CC) const; - - /// \brief Determines whether two calling conventions name the same - /// calling convention. - bool isSameCallConv(CallingConv lcc, CallingConv rcc) { - return (getCanonicalCallConv(lcc) == getCanonicalCallConv(rcc)); - } + /// \brief Retrieves the default calling convention for the current target. + CallingConv getDefaultCallingConvention(bool isVariadic, + bool IsCXXMethod) const; /// \brief Retrieves the "canonical" template name that refers to a /// given template. @@ -1899,6 +1938,12 @@ public: return (*AddrSpaceMap)[AS - LangAS::Offset]; } + bool addressSpaceMapManglingFor(unsigned AS) const { + return AddrSpaceMapMangling || + AS < LangAS::Offset || + AS >= LangAS::Offset + LangAS::Count; + } + private: // Helper for integer ordering unsigned getIntegerRank(const Type *T) const; @@ -1925,7 +1970,6 @@ public: bool isObjCSelType(QualType T) const { return T == getObjCSelType(); } - bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS); bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, bool ForCompare); @@ -2092,12 +2136,15 @@ public: /// it is not used. bool DeclMustBeEmitted(const Decl *D); - void addUnnamedTag(const TagDecl *Tag); - int getUnnamedTagManglingNumber(const TagDecl *Tag) const; + void setManglingNumber(const NamedDecl *ND, unsigned Number); + unsigned getManglingNumber(const NamedDecl *ND) const; + + /// \brief Retrieve the context for computing mangling numbers in the given + /// DeclContext. + MangleNumberingContext &getManglingNumberContext(const DeclContext *DC); + + MangleNumberingContext *createMangleNumberingContext() const; - /// \brief Retrieve the lambda mangling number for a lambda expression. - unsigned getLambdaManglingNumber(CXXMethodDecl *CallOperator); - /// \brief Used by ParmVarDecl to store on the side the /// index of the parameter when it exceeds the size of the normal bitfield. void setParameterIndex(const ParmVarDecl *D, unsigned index); @@ -2105,7 +2152,12 @@ public: /// \brief Used by ParmVarDecl to retrieve on the side the /// index of the parameter when it exceeds the size of the normal bitfield. unsigned getParameterIndex(const ParmVarDecl *D) const; - + + /// \brief Get the storage for the constant value of a materialized temporary + /// of static storage duration. + APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E, + bool MayCreate); + //===--------------------------------------------------------------------===// // Statistics //===--------------------------------------------------------------------===// @@ -2197,93 +2249,21 @@ private: const ObjCImplementationDecl *Impl) const; private: - /// \brief A set of deallocations that should be performed when the + /// \brief A set of deallocations that should be performed when the /// ASTContext is destroyed. - SmallVector<std::pair<void (*)(void*), void *>, 16> Deallocations; - + typedef llvm::SmallDenseMap<void(*)(void*), llvm::SmallVector<void*, 16> > + DeallocationMap; + DeallocationMap Deallocations; + // FIXME: This currently contains the set of StoredDeclMaps used // by DeclContext objects. This probably should not be in ASTContext, // but we include it here so that ASTContext can quickly deallocate them. llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM; - /// \brief A counter used to uniquely identify "blocks". - mutable unsigned int UniqueBlockByRefTypeID; - friend class DeclContext; friend class DeclarationNameTable; void ReleaseDeclContextMaps(); - /// \brief A \c RecursiveASTVisitor that builds a map from nodes to their - /// parents as defined by the \c RecursiveASTVisitor. - /// - /// Note that the relationship described here is purely in terms of AST - /// traversal - there are other relationships (for example declaration context) - /// in the AST that are better modeled by special matchers. - /// - /// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes. - class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> { - public: - /// \brief Builds and returns the translation unit's parent map. - /// - /// The caller takes ownership of the returned \c ParentMap. - static ParentMap *buildMap(TranslationUnitDecl &TU) { - ParentMapASTVisitor Visitor(new ParentMap); - Visitor.TraverseDecl(&TU); - return Visitor.Parents; - } - - private: - typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase; - - ParentMapASTVisitor(ParentMap *Parents) : Parents(Parents) { - } - - bool shouldVisitTemplateInstantiations() const { - return true; - } - bool shouldVisitImplicitCode() const { - return true; - } - // Disables data recursion. We intercept Traverse* methods in the RAV, which - // are not triggered during data recursion. - bool shouldUseDataRecursionFor(clang::Stmt *S) const { - return false; - } - - template <typename T> - bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) { - if (Node == NULL) - return true; - if (ParentStack.size() > 0) - // FIXME: Currently we add the same parent multiple times, for example - // when we visit all subexpressions of template instantiations; this is - // suboptimal, bug benign: the only way to visit those is with - // hasAncestor / hasParent, and those do not create new matches. - // The plan is to enable DynTypedNode to be storable in a map or hash - // map. The main problem there is to implement hash functions / - // comparison operators for all types that DynTypedNode supports that - // do not have pointer identity. - (*Parents)[Node].push_back(ParentStack.back()); - ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node)); - bool Result = (this ->* traverse) (Node); - ParentStack.pop_back(); - return Result; - } - - bool TraverseDecl(Decl *DeclNode) { - return TraverseNode(DeclNode, &VisitorBase::TraverseDecl); - } - - bool TraverseStmt(Stmt *StmtNode) { - return TraverseNode(StmtNode, &VisitorBase::TraverseStmt); - } - - ParentMap *Parents; - llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack; - - friend class RecursiveASTVisitor<ParentMapASTVisitor>; - }; - llvm::OwningPtr<ParentMap> AllParents; }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h b/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h index 64e955e..1635511 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define ASTSTART #include "clang/Basic/DiagnosticASTKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTFwd.h b/contrib/llvm/tools/clang/include/clang/AST/ASTFwd.h new file mode 100644 index 0000000..4f32798 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTFwd.h @@ -0,0 +1,28 @@ +//===--- ASTFwd.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--------------------------------------------------------------===// +/// +/// \file +/// \brief Forward declaration of all AST node types. +/// +//===-------------------------------------------------------------===// + +namespace clang { + +class Decl; +#define DECL(DERIVED, BASE) class DERIVED##Decl; +#include "clang/AST/DeclNodes.inc" +class Stmt; +#define STMT(DERIVED, BASE) class DERIVED; +#include "clang/AST/StmtNodes.inc" +class Type; +#define TYPE(DERIVED, BASE) class DERIVED##Type; +#include "clang/AST/TypeNodes.def" +class CXXCtorInitializer; + +} // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h b/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h index 1672ab2..b74c8ee 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTImporter.h @@ -271,6 +271,14 @@ namespace clang { /// Subclasses can override this function to observe all of the \c From -> /// \c To declaration mappings as they are imported. virtual Decl *Imported(Decl *From, Decl *To); + + /// \brief Called by StructuralEquivalenceContext. If a RecordDecl is + /// being compared to another RecordDecl as part of import, completing the + /// other RecordDecl may trigger importation of the first RecordDecl. This + /// happens especially for anonymous structs. If the original of the second + /// RecordDecl can be found, we can complete it without the need for + /// importation, eliminating this loop. + virtual Decl *GetOriginalDecl(Decl *To) { return NULL; } /// \brief Determine whether the given types are structurally /// equivalent. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTLambda.h b/contrib/llvm/tools/clang/include/clang/AST/ASTLambda.h new file mode 100644 index 0000000..358ac71 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTLambda.h @@ -0,0 +1,80 @@ +//===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file provides some common utility functions for processing +/// Lambda related AST Constructs. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_LAMBDA_H +#define LLVM_CLANG_AST_LAMBDA_H + +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" + +namespace clang { +inline StringRef getLambdaStaticInvokerName() { + return "__invoke"; +} +// This function returns true if M is a specialization, a template, +// or a non-generic lambda call operator. +inline bool isLambdaCallOperator(const CXXMethodDecl *MD) { + const CXXRecordDecl *LambdaClass = MD->getParent(); + if (!LambdaClass || !LambdaClass->isLambda()) return false; + return MD->getOverloadedOperator() == OO_Call; +} + +inline bool isLambdaCallOperator(const DeclContext *DC) { + if (!DC || !isa<CXXMethodDecl>(DC)) return false; + return isLambdaCallOperator(cast<CXXMethodDecl>(DC)); +} + +inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) { + if (!MD) return false; + CXXRecordDecl *LambdaClass = MD->getParent(); + if (LambdaClass && LambdaClass->isGenericLambda()) + return isLambdaCallOperator(MD) && + MD->isFunctionTemplateSpecialization(); + return false; +} + +inline bool isLambdaConversionOperator(CXXConversionDecl *C) { + return C ? C->getParent()->isLambda() : false; +} + +inline bool isLambdaConversionOperator(Decl *D) { + if (!D) return false; + if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D)) + return isLambdaConversionOperator(Conv); + if (FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(D)) + if (CXXConversionDecl *Conv = + dyn_cast_or_null<CXXConversionDecl>(F->getTemplatedDecl())) + return isLambdaConversionOperator(Conv); + return false; +} + +inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) { + return isGenericLambdaCallOperatorSpecialization( + dyn_cast<CXXMethodDecl>(DC)); +} + + +// This returns the parent DeclContext ensuring that the correct +// parent DeclContext is returned for Lambdas +inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) { + if (isLambdaCallOperator(DC)) + return DC->getParent()->getParent(); + else + return DC->getParent(); +} + +} // clang + +#endif // LLVM_CLANG_AST_LAMBDA_H diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h index 6b70285..6d12a92 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h @@ -27,8 +27,11 @@ namespace clang { class ObjCContainerDecl; class ObjCInterfaceDecl; class ObjCPropertyDecl; + class QualType; class TagDecl; class VarDecl; + class VarTemplateDecl; + class VarTemplateSpecializationDecl; /// \brief An abstract interface that should be implemented by listeners /// that want to be notified when an AST entity gets modified after its @@ -53,9 +56,18 @@ public: /// \brief A template specialization (or partial one) was added to the /// template declaration. + virtual void + AddedCXXTemplateSpecialization(const VarTemplateDecl *TD, + const VarTemplateSpecializationDecl *D) {} + + /// \brief A template specialization (or partial one) was added to the + /// template declaration. virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, const FunctionDecl *D) {} + /// \brief A function's return type has been deduced. + virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType); + /// \brief An implicit member got a definition. virtual void CompletedImplicitDefinition(const FunctionDecl *D) {} @@ -78,6 +90,11 @@ public: const ObjCPropertyDecl *OrigProp, const ObjCCategoryDecl *ClassExt) {} + /// \brief A declaration is marked used which was not previously marked used. + /// + /// \param D the declaration marked used + virtual void DeclarationMarkedUsed(const Decl *D) {} + // NOTE: If new methods are added they should also be added to // MultiplexASTMutationListener. }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h b/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h index 4688b12..087ad56 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h @@ -7,22 +7,132 @@ // //===----------------------------------------------------------------------===// // -// 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. +// Provides a dynamic type identifier and 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_AST_TYPE_TRAITS_H #define LLVM_CLANG_AST_AST_TYPE_TRAITS_H +#include "clang/AST/ASTFwd.h" #include "clang/AST/Decl.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Stmt.h" +#include "clang/AST/TemplateBase.h" #include "clang/AST/TypeLoc.h" +#include "clang/Basic/LLVM.h" #include "llvm/Support/AlignOf.h" +namespace llvm { + +class raw_ostream; + +} + namespace clang { + +struct PrintingPolicy; + namespace ast_type_traits { +/// \brief Kind identifier. +/// +/// It can be constructed from any node kind and allows for runtime type +/// hierarchy checks. +/// Use getFromNodeKind<T>() to construct them. +class ASTNodeKind { +public: + /// \brief Empty identifier. It matches nothing. + ASTNodeKind() : KindId(NKI_None) {} + + /// \brief Construct an identifier for T. + template <class T> + static ASTNodeKind getFromNodeKind() { + return ASTNodeKind(KindToKindId<T>::Id); + } + + /// \brief Returns \c true if \c this and \c Other represent the same kind. + bool isSame(ASTNodeKind Other) const; + + /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other. + bool isBaseOf(ASTNodeKind Other) const; + + /// \brief String representation of the kind. + StringRef asStringRef() const; + +private: + /// \brief Kind ids. + /// + /// Includes all possible base and derived kinds. + enum NodeKindId { + NKI_None, + NKI_CXXCtorInitializer, + NKI_TemplateArgument, + NKI_NestedNameSpecifier, + NKI_NestedNameSpecifierLoc, + NKI_QualType, + NKI_TypeLoc, + NKI_Decl, +#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl, +#include "clang/AST/DeclNodes.inc" + NKI_Stmt, +#define STMT(DERIVED, BASE) NKI_##DERIVED, +#include "clang/AST/StmtNodes.inc" + NKI_Type, +#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, +#include "clang/AST/TypeNodes.def" + NKI_NumberOfKinds + }; + + /// \brief Use getFromNodeKind<T>() to construct the kind. + ASTNodeKind(NodeKindId KindId) : KindId(KindId) {} + + /// \brief Returns \c true if \c Base is a base kind of (or same as) \c + /// Derived. + static bool isBaseOf(NodeKindId Base, NodeKindId Derived); + + /// \brief Helper meta-function to convert a kind T to its enum value. + /// + /// This struct is specialized below for all known kinds. + template <class T> struct KindToKindId { + static const NodeKindId Id = NKI_None; + }; + + /// \brief Per kind info. + struct KindInfo { + /// \brief The id of the parent kind, or None if it has no parent. + NodeKindId ParentId; + /// \brief Name of the kind. + const char *Name; + }; + static const KindInfo AllKindInfo[NKI_NumberOfKinds]; + + NodeKindId KindId; +}; + +#define KIND_TO_KIND_ID(Class) \ + template <> struct ASTNodeKind::KindToKindId<Class> { \ + static const NodeKindId Id = NKI_##Class; \ + }; +KIND_TO_KIND_ID(CXXCtorInitializer) +KIND_TO_KIND_ID(TemplateArgument) +KIND_TO_KIND_ID(NestedNameSpecifier) +KIND_TO_KIND_ID(NestedNameSpecifierLoc) +KIND_TO_KIND_ID(QualType) +KIND_TO_KIND_ID(TypeLoc) +KIND_TO_KIND_ID(Decl) +KIND_TO_KIND_ID(Stmt) +KIND_TO_KIND_ID(Type) +#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl) +#include "clang/AST/DeclNodes.inc" +#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED) +#include "clang/AST/StmtNodes.inc" +#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) +#include "clang/AST/TypeNodes.def" +#undef KIND_TO_KIND_ID + /// \brief A dynamically typed AST node container. /// /// Stores an AST node in a type safe way. This allows writing code that @@ -32,7 +142,7 @@ namespace ast_type_traits { /// 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; +/// See \c ASTNodeKind 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 { @@ -49,15 +159,15 @@ public: /// 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. + /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) 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); + return BaseConverter<T>::get(NodeKind, Storage.buffer); } /// \brief Returns a pointer that identifies the stored AST node. @@ -67,142 +177,171 @@ public: /// method returns NULL. const void *getMemoizationData() const; + /// \brief Prints the node to the given output stream. + void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const; + + /// \brief Dumps the node to the given output stream. + void dump(llvm::raw_ostream &OS, SourceManager &SM) const; + + /// \brief For nodes which represent textual entities in the source code, + /// return their SourceRange. For all other nodes, return SourceRange(). + SourceRange getSourceRange() const; + + /// @{ + /// \brief Imposes an order on \c DynTypedNode. + /// + /// Supports comparison of nodes that support memoization. + /// FIXME: Implement comparsion for other node types (currently + /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data). + bool operator<(const DynTypedNode &Other) const { + assert(getMemoizationData() && Other.getMemoizationData()); + return getMemoizationData() < Other.getMemoizationData(); + } + bool operator==(const DynTypedNode &Other) const { + // Nodes with different types cannot be equal. + if (!NodeKind.isSame(Other.NodeKind)) + return false; + + // FIXME: Implement for other types. + if (ASTNodeKind::getFromNodeKind<QualType>().isBaseOf(NodeKind)) { + return *get<QualType>() == *Other.get<QualType>(); + } + assert(getMemoizationData() && Other.getMemoizationData()); + return getMemoizationData() == Other.getMemoizationData(); + } + bool operator!=(const DynTypedNode &Other) const { + return !operator==(Other); + } + /// @} + 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 Converter that uses dyn_cast<T> from a stored BaseT*. + template <typename T, typename BaseT> struct DynCastPtrConverter { + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind)) + return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage)); + return NULL; + } + static DynTypedNode create(const BaseT &Node) { + DynTypedNode Result; + Result.NodeKind = ASTNodeKind::getFromNodeKind<T>(); + new (Result.Storage.buffer) const BaseT * (&Node); + return Result; + } + }; + + /// \brief Converter that stores T* (by pointer). + template <typename T> struct PtrConverter { + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind)) + return *reinterpret_cast<T *const *>(Storage); + return NULL; + } + static DynTypedNode create(const T &Node) { + DynTypedNode Result; + Result.NodeKind = ASTNodeKind::getFromNodeKind<T>(); + new (Result.Storage.buffer) const T * (&Node); + return Result; + } + }; + + /// \brief Converter that stores T (by value). + template <typename T> struct ValueConverter { + static const T *get(ASTNodeKind NodeKind, const char Storage[]) { + if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind)) + return reinterpret_cast<const T *>(Storage); + return NULL; + } + static DynTypedNode create(const T &Node) { + DynTypedNode Result; + Result.NodeKind = ASTNodeKind::getFromNodeKind<T>(); + new (Result.Storage.buffer) T(Node); + return Result; + } + }; + + ASTNodeKind NodeKind; /// \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 + /// Note that we can store \c Decls, \c Stmts, \c Types, + /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are + /// guaranteed to be unique pointers pointing to dedicated storage in the AST. + /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and + /// \c TemplateArguments on the other hand do not have storage or unique /// pointers and thus need to be stored by value. - llvm::AlignedCharArrayUnion<Decl *, Stmt *, NestedNameSpecifier, - NestedNameSpecifierLoc, QualType, Type, - TypeLoc> Storage; + typedef llvm::AlignedCharArrayUnion< + Decl *, Stmt *, Type *, NestedNameSpecifier *, CXXCtorInitializer *> + KindsByPointer; + llvm::AlignedCharArrayUnion<KindsByPointer, TemplateArgument, + NestedNameSpecifierLoc, QualType, TypeLoc> + 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; - } -}; +template <typename T> +struct DynTypedNode::BaseConverter< + T, typename llvm::enable_if<llvm::is_base_of< + Decl, T> >::type> : public DynCastPtrConverter<T, Decl> {}; + +template <typename T> +struct DynTypedNode::BaseConverter< + T, typename llvm::enable_if<llvm::is_base_of< + Stmt, T> >::type> : public DynCastPtrConverter<T, Stmt> {}; + +template <typename T> +struct DynTypedNode::BaseConverter< + T, typename llvm::enable_if<llvm::is_base_of< + Type, T> >::type> : public DynCastPtrConverter<T, Type> {}; + +template <> +struct DynTypedNode::BaseConverter< + NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {}; + +template <> +struct DynTypedNode::BaseConverter< + CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {}; + +template <> +struct DynTypedNode::BaseConverter< + TemplateArgument, void> : public ValueConverter<TemplateArgument> {}; + +template <> +struct DynTypedNode::BaseConverter< + NestedNameSpecifierLoc, + void> : public ValueConverter<NestedNameSpecifierLoc> {}; + +template <> +struct DynTypedNode::BaseConverter<QualType, + void> : public ValueConverter<QualType> {}; + +template <> +struct DynTypedNode::BaseConverter< + TypeLoc, void> : public ValueConverter<TypeLoc> {}; + // 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; } + static const T *get(ASTNodeKind NodeKind, 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; - }; + if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(NodeKind)) { + return BaseConverter<Decl>::get(NodeKind, Storage.buffer); + } else if (ASTNodeKind::getFromNodeKind<Stmt>().isBaseOf(NodeKind)) { + return BaseConverter<Stmt>::get(NodeKind, Storage.buffer); + } else if (ASTNodeKind::getFromNodeKind<Type>().isBaseOf(NodeKind)) { + return BaseConverter<Type>::get(NodeKind, Storage.buffer); + } else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) { + return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer); + } + return NULL; } } // end namespace ast_type_traits diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTUnresolvedSet.h b/contrib/llvm/tools/clang/include/clang/AST/ASTUnresolvedSet.h index 5a56b4d..e8be670 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTUnresolvedSet.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTUnresolvedSet.h @@ -22,12 +22,21 @@ namespace clang { /// \brief An UnresolvedSet-like class which uses the ASTContext's allocator. class ASTUnresolvedSet { - typedef ASTVector<DeclAccessPair> DeclsTy; + struct DeclsTy : ASTVector<DeclAccessPair> { + DeclsTy() {} + DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {} + + bool isLazy() const { return getTag(); } + void setLazy(bool Lazy) { setTag(Lazy); } + }; + DeclsTy Decls; ASTUnresolvedSet(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION; void operator=(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION; + friend class LazyASTUnresolvedSet; + public: ASTUnresolvedSet() {} ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {} @@ -48,7 +57,7 @@ public: /// Replaces the given declaration with the new one, once. /// /// \return true if the set changed - bool replace(const NamedDecl* Old, NamedDecl *New, AccessSpecifier AS) { + bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) { for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) { if (I->getDecl() == Old) { I->set(New, AS); @@ -58,10 +67,7 @@ public: return false; } - void erase(unsigned I) { - Decls[I] = Decls.back(); - Decls.pop_back(); - } + void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); } void clear() { Decls.clear(); } @@ -79,7 +85,29 @@ public: DeclAccessPair &operator[](unsigned I) { return Decls[I]; } const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; } }; - + +/// \brief An UnresolvedSet-like class that might not have been loaded from the +/// external AST source yet. +class LazyASTUnresolvedSet { + mutable ASTUnresolvedSet Impl; + + void getFromExternalSource(ASTContext &C) const; + +public: + ASTUnresolvedSet &get(ASTContext &C) const { + if (Impl.Decls.isLazy()) + getFromExternalSource(C); + return Impl; + } + + void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); } + void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) { + assert(Impl.empty() || Impl.Decls.isLazy()); + Impl.Decls.setLazy(true); + Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS); + } +}; + } // namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h b/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h index 669e50d..6db918e 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTVector.h @@ -55,16 +55,24 @@ namespace clang { template<typename T> class ASTVector { - T *Begin, *End, *Capacity; +private: + T *Begin, *End; + llvm::PointerIntPair<T*, 1, bool> Capacity; void setEnd(T *P) { this->End = P; } +protected: + // Make a tag bit available to users of this class. + // FIXME: This is a horrible hack. + bool getTag() const { return Capacity.getInt(); } + void setTag(bool B) { Capacity.setInt(B); } + public: // Default ctor - Initialize to empty. - ASTVector() : Begin(NULL), End(NULL), Capacity(NULL) { } + ASTVector() : Begin(0), End(0), Capacity(0, false) {} - ASTVector(ASTContext &C, unsigned N) - : Begin(NULL), End(NULL), Capacity(NULL) { + ASTVector(const ASTContext &C, unsigned N) + : Begin(0), End(0), Capacity(0, false) { reserve(C, N); } @@ -155,8 +163,8 @@ public: return const_pointer(Begin); } - void push_back(const_reference Elt, ASTContext &C) { - if (End < Capacity) { + void push_back(const_reference Elt, const ASTContext &C) { + if (End < this->capacity_ptr()) { Retry: new (End) T(Elt); ++End; @@ -166,19 +174,19 @@ public: goto Retry; } - void reserve(ASTContext &C, unsigned N) { - if (unsigned(Capacity-Begin) < N) + void reserve(const ASTContext &C, unsigned N) { + if (unsigned(this->capacity_ptr()-Begin) < N) grow(C, N); } /// capacity - Return the total number of elements in the currently allocated /// buffer. - size_t capacity() const { return Capacity - Begin; } + size_t capacity() const { return this->capacity_ptr() - Begin; } /// append - Add the specified range to the end of the SmallVector. /// template<typename in_iter> - void append(ASTContext &C, in_iter in_start, in_iter in_end) { + void append(const ASTContext &C, in_iter in_start, in_iter in_end) { size_type NumInputs = std::distance(in_start, in_end); if (NumInputs == 0) @@ -197,7 +205,7 @@ public: /// append - Add the specified range to the end of the SmallVector. /// - void append(ASTContext &C, size_type NumInputs, const T &Elt) { + void append(const ASTContext &C, size_type NumInputs, const T &Elt) { // Grow allocated space if needed. if (NumInputs > size_type(this->capacity_ptr()-this->end())) this->grow(C, this->size()+NumInputs); @@ -214,13 +222,13 @@ public: std::uninitialized_copy(I, E, Dest); } - iterator insert(ASTContext &C, iterator I, const T &Elt) { + iterator insert(const ASTContext &C, iterator I, const T &Elt) { if (I == this->end()) { // Important special case for empty vector. - push_back(Elt); + push_back(Elt, C); return this->end()-1; } - if (this->EndX < this->CapacityX) { + if (this->End < this->capacity_ptr()) { Retry: new (this->end()) T(this->back()); this->setEnd(this->end()+1); @@ -235,7 +243,7 @@ public: goto Retry; } - iterator insert(ASTContext &C, iterator I, size_type NumToInsert, + iterator insert(const ASTContext &C, iterator I, size_type NumToInsert, const T &Elt) { if (I == this->end()) { // Important special case for empty vector. append(C, NumToInsert, Elt); @@ -284,7 +292,7 @@ public: } template<typename ItTy> - iterator insert(ASTContext &C, iterator I, ItTy From, ItTy To) { + iterator insert(const ASTContext &C, iterator I, ItTy From, ItTy To) { if (I == this->end()) { // Important special case for empty vector. append(C, From, To); return this->end()-1; @@ -335,7 +343,7 @@ public: return I; } - void resize(ASTContext &C, unsigned N, const T &NV) { + void resize(const ASTContext &C, unsigned N, const T &NV) { if (N < this->size()) { this->destroy_range(this->begin()+N, this->end()); this->setEnd(this->begin()+N); @@ -350,7 +358,7 @@ public: private: /// grow - double the size of the allocated memory, guaranteeing space for at /// least one more element or MinSize if specified. - void grow(ASTContext &C, size_type MinSize = 1); + void grow(const ASTContext &C, size_type MinSize = 1); void construct_range(T *S, T *E, const T &Elt) { for (; S != E; ++S) @@ -365,13 +373,16 @@ private: } protected: - iterator capacity_ptr() { return (iterator)this->Capacity; } + const_iterator capacity_ptr() const { + return (iterator) Capacity.getPointer(); + } + iterator capacity_ptr() { return (iterator)Capacity.getPointer(); } }; // Define this out-of-line to dissuade the C++ compiler from inlining it. template <typename T> -void ASTVector<T>::grow(ASTContext &C, size_t MinSize) { - size_t CurCapacity = Capacity-Begin; +void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) { + size_t CurCapacity = this->capacity(); size_t CurSize = size(); size_t NewCapacity = 2*CurCapacity; if (NewCapacity < MinSize) @@ -394,7 +405,7 @@ void ASTVector<T>::grow(ASTContext &C, size_t MinSize) { // ASTContext never frees any memory. Begin = NewElts; End = NewElts+CurSize; - Capacity = Begin+NewCapacity; + Capacity.setPointer(Begin+NewCapacity); } } // end: clang namespace diff --git a/contrib/llvm/tools/clang/include/clang/AST/Attr.h b/contrib/llvm/tools/clang/include/clang/AST/Attr.h index 27dcef2..7dbf413 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Attr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Attr.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_ATTR_H #include "clang/AST/AttrIterator.h" +#include "clang/AST/Decl.h" #include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/LLVM.h" @@ -145,7 +146,7 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { // Relies on relative order of enum emission with respect to param attrs. - return (A->getKind() <= attr::LAST_MS_INHERITABLE && + return (A->getKind() <= attr::LAST_MS_INHERITANCE && A->getKind() > attr::LAST_INHERITABLE_PARAM); } }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h index 2983e04..dbe4ad0 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h @@ -287,9 +287,9 @@ public: // Iterate over the set of overriding virtual methods in a given // subobject. - typedef SmallVector<UniqueVirtualMethod, 4>::iterator + typedef SmallVectorImpl<UniqueVirtualMethod>::iterator overriding_iterator; - typedef SmallVector<UniqueVirtualMethod, 4>::const_iterator + typedef SmallVectorImpl<UniqueVirtualMethod>::const_iterator overriding_const_iterator; // Add a new overriding method for a particular subobject. diff --git a/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h b/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h index 9460757..9c699b7 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CanonicalType.h @@ -81,7 +81,7 @@ public: operator QualType() const { return Stored; } /// \brief Implicit conversion to bool. - operator bool() const { return !isNull(); } + LLVM_EXPLICIT operator bool() const { return !isNull(); } bool isNull() const { return Stored.isNull(); diff --git a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h index 082c672..09ff682 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h @@ -19,21 +19,20 @@ #include "llvm/Support/MathExtras.h" namespace clang { - + /// CharUnits - This is an opaque type for sizes expressed in character units. - /// Instances of this type represent a quantity as a multiple of the size + /// Instances of this type represent a quantity as a multiple of the size /// of the standard C type, char, on the target architecture. As an opaque /// type, CharUnits protects you from accidentally combining operations on - /// quantities in bit units and character units. + /// quantities in bit units and character units. + /// + /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned + /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to + /// the same quantity of storage. However, we use the term 'character unit' + /// rather than 'byte' to avoid an implication that a character unit is + /// exactly 8 bits. /// - /// It should be noted that characters and bytes are distinct concepts. Bytes - /// refer to addressable units of data storage on the target machine, and - /// characters are members of a set of elements used for the organization, - /// control, or representation of data. According to C99, bytes are allowed - /// to exceed characters in size, although currently, clang only supports - /// architectures where the two are the same size. - /// - /// For portability, never assume that a target character is 8 bits wide. Use + /// For portability, never assume that a target character is 8 bits wide. Use /// CharUnit values wherever you calculate sizes, offsets, or alignments /// in character units. class CharUnits { diff --git a/contrib/llvm/tools/clang/include/clang/AST/Comment.h b/contrib/llvm/tools/clang/include/clang/AST/Comment.h index c02a82f..28849f5 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Comment.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Comment.h @@ -699,7 +699,10 @@ private: unsigned ParamIndex; public: - enum { InvalidParamIndex = ~0U }; + enum LLVM_ENUM_INT_TYPE(unsigned) { + InvalidParamIndex = ~0U, + VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U + }; ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, @@ -755,14 +758,25 @@ public: return ParamIndex != InvalidParamIndex; } + bool isVarArgParam() const LLVM_READONLY { + return ParamIndex == VarArgParamIndex; + } + + void setIsVarArgParam() { + ParamIndex = VarArgParamIndex; + assert(isParamIndexValid()); + } + unsigned getParamIndex() const LLVM_READONLY { assert(isParamIndexValid()); + assert(!isVarArgParam()); return ParamIndex; } void setParamIndex(unsigned Index) { ParamIndex = Index; assert(isParamIndexValid()); + assert(!isVarArgParam()); } }; @@ -1097,10 +1111,6 @@ public: return ThisDeclInfo; } - DeclInfo *getThisDeclInfo() const LLVM_READONLY { - return ThisDeclInfo; - } - ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; } }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h b/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h index d1f5209..dde7a14 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentCommandTraits.h @@ -67,6 +67,9 @@ struct CommandInfo { /// a template parameter (\\tparam or an alias). unsigned IsTParamCommand : 1; + /// True if this command is \\throws or an alias. + unsigned IsThrowsCommand : 1; + /// True if this command is \\deprecated or an alias. unsigned IsDeprecatedCommand : 1; @@ -142,6 +145,8 @@ public: llvm_unreachable("the command should be known"); } + const CommandInfo *getTypoCorrectCommandInfo(StringRef Typo) const; + const CommandInfo *getCommandInfo(unsigned CommandID) const; const CommandInfo *registerUnknownCommand(StringRef CommandName); diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td b/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td index 8c88494..ed323da 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentCommands.td @@ -15,6 +15,7 @@ class Command<string name> { bit IsReturnsCommand = 0; bit IsParamCommand = 0; bit IsTParamCommand = 0; + bit IsThrowsCommand = 0; bit IsDeprecatedCommand = 0; bit IsHeaderfileCommand = 0; @@ -109,6 +110,10 @@ def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; } // HeaderDoc command for template parameter documentation. def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; } +def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; } +def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; } +def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; } + def Deprecated : BlockCommand<"deprecated"> { let IsEmptyParagraphAllowed = 1; let IsDeprecatedCommand = 1; @@ -200,11 +205,17 @@ def Mainpage : VerbatimLineCommand<"mainpage">; def Subpage : VerbatimLineCommand<"subpage">; def Ref : VerbatimLineCommand<"ref">; +def Relates : VerbatimLineCommand<"relates">; +def Related : VerbatimLineCommand<"related">; +def RelatesAlso : VerbatimLineCommand<"relatesalso">; +def RelatedAlso : VerbatimLineCommand<"relatedalso">; + //===----------------------------------------------------------------------===// // DeclarationVerbatimLineCommand //===----------------------------------------------------------------------===// // Doxygen commands. +def Def : DeclarationVerbatimLineCommand<"def">; def Fn : DeclarationVerbatimLineCommand<"fn">; def Namespace : DeclarationVerbatimLineCommand<"namespace">; def Overload : DeclarationVerbatimLineCommand<"overload">; diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentDiagnostic.h b/contrib/llvm/tools/clang/include/clang/AST/CommentDiagnostic.h index 6e89410..312da06 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define COMMENTSTART #include "clang/Basic/DiagnosticCommentKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h b/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h index d6a1072..7e00813 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentParser.h @@ -61,10 +61,8 @@ class Parser { void consumeToken() { if (MoreLATokens.empty()) L.lex(Tok); - else { - Tok = MoreLATokens.back(); - MoreLATokens.pop_back(); - } + else + Tok = MoreLATokens.pop_back_val(); } void putBack(const Token &OldTok) { diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h b/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h index 15e454d..3910960 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h @@ -58,9 +58,6 @@ class Sema { /// AST node for the \\brief command and its aliases. const BlockCommandComment *BriefCommand; - /// AST node for the \\returns command and its aliases. - const BlockCommandComment *ReturnsCommand; - /// AST node for the \\headerfile command. const BlockCommandComment *HeaderfileCommand; @@ -211,7 +208,11 @@ public: bool isFunctionDecl(); bool isAnyFunctionDecl(); + + /// \returns \c true if declaration that this comment is attached to declares + /// a function pointer. bool isFunctionPointerVarDecl(); + bool isFunctionOrMethodVariadic(); bool isObjCMethodDecl(); bool isObjCPropertyDecl(); bool isTemplateOrSpecialization(); @@ -220,6 +221,8 @@ public: bool isUnionDecl(); bool isObjCInterfaceDecl(); bool isObjCProtocolDecl(); + bool isClassTemplateDecl(); + bool isFunctionTemplateDecl(); ArrayRef<const ParmVarDecl *> getParamVars(); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Decl.h b/contrib/llvm/tools/clang/include/clang/AST/Decl.h index a0c76c0..244a7b8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Decl.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Decl.h @@ -24,6 +24,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" namespace clang { struct ASTTemplateArgumentListInfo; @@ -43,6 +44,7 @@ class TemplateArgumentList; class TemplateParameterList; class TypeLoc; class UnresolvedSetImpl; +class VarTemplateDecl; /// \brief A container of type source information. /// @@ -109,7 +111,6 @@ class NamedDecl : public Decl { private: NamedDecl *getUnderlyingDeclImpl(); - void verifyLinkage() const; protected: NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) @@ -142,7 +143,7 @@ public: // FIXME: Deprecated, move clients to getName(). std::string getNameAsString() const { return Name.getAsString(); } - void printName(raw_ostream &os) const { return Name.printName(os); } + void printName(raw_ostream &os) const { os << Name; } /// getDeclName - Get the actual, stored name of the declaration, /// which may be a special name. @@ -189,10 +190,13 @@ public: using Decl::isModulePrivate; using Decl::setModulePrivate; - + /// \brief Determine whether this declaration is hidden from name lookup. bool isHidden() const { return Hidden; } - + + /// \brief Set whether this declaration is hidden from name lookup. + void setHidden(bool Hide) { Hidden = Hide; } + /// \brief Determine whether this declaration is a C++ class member. bool isCXXClassMember() const { const DeclContext *DC = getDeclContext(); @@ -212,11 +216,24 @@ public: bool isCXXInstanceMember() const; /// \brief Determine what kind of linkage this entity has. - Linkage getLinkage() const; + /// This is not the linkage as defined by the standard or the codegen notion + /// of linkage. It is just an implementation detail that is used to compute + /// those. + Linkage getLinkageInternal() const; + + /// \brief Get the linkage from a semantic point of view. Entities in + /// anonymous namespaces are external (in c++98). + Linkage getFormalLinkage() const { + return clang::getFormalLinkage(getLinkageInternal()); + } /// \brief True if this decl has external linkage. - bool hasExternalLinkage() const { - return getLinkage() == ExternalLinkage; + bool hasExternalFormalLinkage() const { + return isExternalFormalLinkage(getLinkageInternal()); + } + + bool isExternallyVisible() const { + return clang::isExternallyVisible(getLinkageInternal()); } /// \brief Determines the visibility of this entity. @@ -256,6 +273,13 @@ public: return const_cast<NamedDecl*>(this)->getUnderlyingDecl(); } + NamedDecl *getMostRecentDecl() { + return cast<NamedDecl>(static_cast<Decl *>(this)->getMostRecentDecl()); + } + const NamedDecl *getMostRecentDecl() const { + return const_cast<NamedDecl*>(this)->getMostRecentDecl(); + } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; } }; @@ -351,6 +375,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; /// \brief Returns true if this is an anonymous namespace declaration. /// @@ -377,7 +402,7 @@ public: /// \brief Get the original (first) namespace declaration. NamespaceDecl *getOriginalNamespace() { - if (isFirstDeclaration()) + if (isFirstDecl()) return this; return AnonOrFirstNamespaceAndInline.getPointer(); @@ -385,7 +410,7 @@ public: /// \brief Get the original (first) namespace declaration. const NamespaceDecl *getOriginalNamespace() const { - if (isFirstDeclaration()) + if (isFirstDecl()) return this; return AnonOrFirstNamespaceAndInline.getPointer(); @@ -394,9 +419,7 @@ public: /// \brief Return true if this declaration is an original (first) declaration /// of the namespace. This is false for non-original (subsequent) namespace /// declarations and anonymous namespaces. - bool isOriginalNamespace() const { - return isFirstDeclaration(); - } + bool isOriginalNamespace() const { return isFirstDecl(); } /// \brief Retrieve the anonymous namespace nested inside this namespace, /// if any. @@ -689,11 +712,21 @@ private: /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; + + /// \brief Whether this variable is the implicit variable for a lambda + /// init-capture. + unsigned IsInitCapture : 1; + + /// \brief Whether this local extern variable's previous declaration was + /// declared in the same block scope. This controls whether we should merge + /// the type of this declaration with its previous declaration. + unsigned PreviousDeclInSameBlockScope : 1; }; - enum { NumVarDeclBits = 12 }; + enum { NumVarDeclBits = 14 }; friend class ASTDeclReader; friend class StmtIteratorBase; + friend class ASTNodeImporter; protected: enum { NumParameterIndexBits = 8 }; @@ -732,15 +765,8 @@ protected: }; VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, StorageClass SC) - : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() { - assert(sizeof(VarDeclBitfields) <= sizeof(unsigned)); - assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned)); - AllBits = 0; - VarDeclBits.SClass = SC; - // Everything else is implicitly initialized to false. - } + SourceLocation IdLoc, IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, StorageClass SC); typedef Redeclarable<VarDecl> redeclarable_base; virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); } @@ -757,6 +783,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; static VarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -797,7 +824,8 @@ public: /// is a non-static local variable. bool hasLocalStorage() const { if (getStorageClass() == SC_None) - return !isFileVarDecl(); + // Second check is for C++11 [dcl.stc]p4. + return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified; // Return true for: Auto, Register. // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal. @@ -808,7 +836,10 @@ public: /// isStaticLocal - Returns true if a variable with function scope is a /// static local variable. bool isStaticLocal() const { - return getStorageClass() == SC_Static && !isFileVarDecl(); + return (getStorageClass() == SC_Static || + // C++11 [dcl.stc]p4 + (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local)) + && !isFileVarDecl(); } /// \brief Returns true if a variable has extern or __private_extern__ @@ -818,12 +849,19 @@ public: getStorageClass() == SC_PrivateExtern; } - /// hasGlobalStorage - Returns true for all variables that do not - /// have local storage. This includs all global variables as well - /// as static variables declared within a function. + /// \brief Returns true for all variables that do not have local storage. + /// + /// This includes all global variables as well as static variables declared + /// within a function. bool hasGlobalStorage() const { return !hasLocalStorage(); } - /// Compute the language linkage. + /// \brief Get the storage duration of this variable, per C++ [basic.stc]. + StorageDuration getStorageDuration() const { + return hasLocalStorage() ? SD_Automatic : + getTSCSpec() ? SD_Thread : SD_Static; + } + + /// \brief Compute the language linkage. LanguageLinkage getLanguageLinkage() const; /// \brief Determines whether this variable is a variable with @@ -847,7 +885,7 @@ public: bool isLocalVarDecl() const { if (getKind() != Decl::Var) return false; - if (const DeclContext *DC = getDeclContext()) + if (const DeclContext *DC = getLexicalDeclContext()) return DC->getRedeclContext()->isFunctionOrMethod(); return false; } @@ -857,7 +895,7 @@ public: bool isFunctionOrMethodVarDecl() const { if (getKind() != Decl::Var) return false; - const DeclContext *DC = getDeclContext()->getRedeclContext(); + const DeclContext *DC = getLexicalDeclContext()->getRedeclContext(); return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block; } @@ -908,10 +946,6 @@ public: return const_cast<VarDecl*>(this)->getActingDefinition(); } - /// \brief Determine whether this is a tentative definition of a - /// variable in C. - bool isTentativeDefinitionNow() const; - /// \brief Get the real (not just tentative) definition for this declaration. VarDecl *getDefinition(ASTContext &); const VarDecl *getDefinition(ASTContext &C) const { @@ -933,10 +967,11 @@ public: /// isFileVarDecl - Returns true for file scoped variable declaration. bool isFileVarDecl() const { - if (getKind() != Decl::Var) + Kind K = getKind(); + if (K == ParmVar || K == ImplicitParam) return false; - if (getDeclContext()->getRedeclContext()->isFileContext()) + if (getLexicalDeclContext()->getRedeclContext()->isFileContext()) return true; if (isStaticDataMember()) @@ -1000,20 +1035,6 @@ public: void setInit(Expr *I); - /// \brief Determine whether this variable is a reference that - /// extends the lifetime of its temporary initializer. - /// - /// A reference extends the lifetime of its temporary initializer if - /// it's initializer is an rvalue that would normally go out of scope - /// at the end of the initializer (a full expression). In such cases, - /// the reference itself takes ownership of the temporary, which will - /// be destroyed when the reference goes out of scope. For example: - /// - /// \code - /// const int &r = 1.0; // creates a temporary of type 'int' - /// \endcode - bool extendsLifetimeOfTemporary() const; - /// \brief Determine whether this variable's value can be used in a /// constant expression, according to the relevant language standard. /// This only checks properties of the declaration, and does not check @@ -1123,15 +1144,34 @@ public: bool isConstexpr() const { return VarDeclBits.IsConstexpr; } void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; } + /// Whether this variable is the implicit variable for a lambda init-capture. + bool isInitCapture() const { return VarDeclBits.IsInitCapture; } + void setInitCapture(bool IC) { VarDeclBits.IsInitCapture = IC; } + + /// Whether this local extern variable declaration's previous declaration + /// was declared in the same block scope. Only correct in C++. + bool isPreviousDeclInSameBlockScope() const { + return VarDeclBits.PreviousDeclInSameBlockScope; + } + void setPreviousDeclInSameBlockScope(bool Same) { + VarDeclBits.PreviousDeclInSameBlockScope = Same; + } + /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. VarDecl *getInstantiatedFromStaticDataMember() const; - /// \brief If this variable is a static data member, determine what kind of + /// \brief If this variable is an instantiation of a variable template or a + /// static data member of a class template, determine what kind of /// template specialization or instantiation this is. TemplateSpecializationKind getTemplateSpecializationKind() const; + /// \brief If this variable is an instantiation of a variable template or a + /// static data member of a class template, determine its point of + /// instantiation. + SourceLocation getPointOfInstantiation() const; + /// \brief If this variable is an instantiation of a static data member of a /// class template specialization, retrieves the member specialization /// information. @@ -1142,6 +1182,26 @@ public: void setTemplateSpecializationKind(TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation = SourceLocation()); + /// \brief Specify that this variable is an instantiation of the + /// static data member VD. + void setInstantiationOfStaticDataMember(VarDecl *VD, + TemplateSpecializationKind TSK); + + /// \brief Retrieves the variable template that is described by this + /// variable declaration. + /// + /// Every variable template is represented as a VarTemplateDecl and a + /// VarDecl. The former contains template properties (such as + /// the template parameter lists) while the latter contains the + /// actual description of the template's + /// contents. VarTemplateDecl::getTemplatedDecl() retrieves the + /// VarDecl that from a VarTemplateDecl, while + /// getDescribedVarTemplate() retrieves the VarTemplateDecl from + /// a VarDecl. + VarTemplateDecl *getDescribedVarTemplate() const; + + void setDescribedVarTemplate(VarTemplateDecl *Template); + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; } @@ -1314,11 +1374,7 @@ public: ParmVarDeclBits.HasInheritedDefaultArg = I; } - QualType getOriginalType() const { - if (getTypeSourceInfo()) - return getTypeSourceInfo()->getType(); - return getType(); - } + QualType getOriginalType() const; /// \brief Determine whether this parameter is actually a function /// parameter pack. @@ -1517,6 +1573,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, @@ -1701,6 +1758,10 @@ public: /// entry point into an executable program. bool isMain() const; + /// \brief Determines whether this function is a MSVCRT user defined entry + /// point. + bool isMSVCRTEntryPoint() const; + /// \brief Determines whether this operator new or delete is one /// of the reserved global placement operators: /// void *operator new(size_t, void *); @@ -1716,6 +1777,28 @@ public: /// This function must be an allocation or deallocation function. bool isReservedGlobalPlacementOperator() const; + /// \brief Determines whether this function is one of the replaceable + /// global allocation functions: + /// void *operator new(size_t); + /// void *operator new(size_t, const std::nothrow_t &) noexcept; + /// void *operator new[](size_t); + /// void *operator new[](size_t, const std::nothrow_t &) noexcept; + /// void operator delete(void *) noexcept; + /// void operator delete(void *, std::size_t) noexcept; [C++1y] + /// void operator delete(void *, const std::nothrow_t &) noexcept; + /// void operator delete[](void *) noexcept; + /// void operator delete[](void *, std::size_t) noexcept; [C++1y] + /// void operator delete[](void *, const std::nothrow_t &) noexcept; + /// These functions have special behavior under C++1y [expr.new]: + /// An implementation is allowed to omit a call to a replaceable global + /// allocation function. [...] + bool isReplaceableGlobalAllocationFunction() const; + + /// \brief Determine whether this function is a sized global deallocation + /// function in C++1y. If so, find and return the corresponding unsized + /// deallocation function. + FunctionDecl *getCorrespondingUnsizedGlobalDeallocationFunction() const; + /// Compute the language linkage. LanguageLinkage getLanguageLinkage() const; @@ -2039,7 +2122,7 @@ public: /// FieldDecl - An instance of this class is created by Sema::ActOnField to /// represent a member of a struct/union/class. -class FieldDecl : public DeclaratorDecl { +class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { // FIXME: This can be packed into the bitfields in Decl. bool Mutable : 1; mutable unsigned CachedFieldIndex : 31; @@ -2153,6 +2236,10 @@ public: SourceRange getSourceRange() const LLVM_READONLY; + /// Retrieves the canonical declaration of this field. + FieldDecl *getCanonicalDecl() { return getFirstDecl(); } + const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstField && K <= lastField; } @@ -2165,7 +2252,7 @@ public: /// that is defined. For example, in "enum X {a,b}", each of a/b are /// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a /// TagType for the X EnumDecl. -class EnumConstantDecl : public ValueDecl { +class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> { Stmt *Init; // an integer constant expression llvm::APSInt Val; // The value. protected: @@ -2191,6 +2278,10 @@ public: SourceRange getSourceRange() const LLVM_READONLY; + /// Retrieves the canonical declaration of this enumerator. + EnumConstantDecl *getCanonicalDecl() { return getFirstDecl(); } + const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == EnumConstant; } @@ -2289,14 +2380,14 @@ public: /// Base class for declarations which introduce a typedef-name. class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> { virtual void anchor(); - /// UnderlyingType - This is the type the typedef is set to. - TypeSourceInfo *TInfo; + typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo; + llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo; protected: TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) - : TypeDecl(DK, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {} + : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {} typedef Redeclarable<TypedefNameDecl> redeclarable_base; virtual TypedefNameDecl *getNextRedeclaration() { @@ -2315,26 +2406,31 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; - TypeSourceInfo *getTypeSourceInfo() const { - return TInfo; - } + bool isModed() const { return MaybeModedTInfo.is<ModedTInfo*>(); } - /// Retrieves the canonical declaration of this typedef-name. - TypedefNameDecl *getCanonicalDecl() { - return getFirstDeclaration(); - } - const TypedefNameDecl *getCanonicalDecl() const { - return getFirstDeclaration(); + TypeSourceInfo *getTypeSourceInfo() const { + return isModed() + ? MaybeModedTInfo.get<ModedTInfo*>()->first + : MaybeModedTInfo.get<TypeSourceInfo*>(); } - QualType getUnderlyingType() const { - return TInfo->getType(); + return isModed() + ? MaybeModedTInfo.get<ModedTInfo*>()->second + : MaybeModedTInfo.get<TypeSourceInfo*>()->getType(); } void setTypeSourceInfo(TypeSourceInfo *newType) { - TInfo = newType; + MaybeModedTInfo = newType; + } + void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) { + MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy); } + /// Retrieves the canonical declaration of this typedef-name. + TypedefNameDecl *getCanonicalDecl() { return getFirstDecl(); } + const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { @@ -2436,6 +2532,9 @@ protected: /// This option is only enabled when modules are enabled. bool MayHaveOutOfDateDef : 1; + /// Has the full definition of this type been required by a use somewhere in + /// the TU. + bool IsCompleteDefinitionRequired : 1; private: SourceLocation RBraceLoc; @@ -2443,33 +2542,33 @@ private: // to be used for the (uncommon) case of out-of-line declarations. typedef QualifierInfo ExtInfo; - /// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name + /// \brief If the (out-of-line) tag declaration name /// is qualified, it points to the qualifier info (nns and range); /// otherwise, if the tag declaration is anonymous and it is part of /// a typedef or alias, it points to the TypedefNameDecl (used for mangling); + /// otherwise, if the tag declaration is anonymous and it is used as a + /// declaration specifier for variables, it points to the first VarDecl (used + /// for mangling); /// otherwise, it is a null (TypedefNameDecl) pointer. - llvm::PointerUnion<TypedefNameDecl*, ExtInfo*> TypedefNameDeclOrQualifier; + llvm::PointerUnion<NamedDecl *, ExtInfo *> NamedDeclOrQualifier; - bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo*>(); } - ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo*>(); } + bool hasExtInfo() const { return NamedDeclOrQualifier.is<ExtInfo *>(); } + ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get<ExtInfo *>(); } const ExtInfo *getExtInfo() const { - return TypedefNameDeclOrQualifier.get<ExtInfo*>(); + return NamedDeclOrQualifier.get<ExtInfo *>(); } protected: - TagDecl(Kind DK, TagKind TK, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - TagDecl *PrevDecl, SourceLocation StartL) - : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), - TypedefNameDeclOrQualifier((TypedefNameDecl*) 0) { + TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, + IdentifierInfo *Id, TagDecl *PrevDecl, SourceLocation StartL) + : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), TagDeclKind(TK), + IsCompleteDefinition(false), IsBeingDefined(false), + IsEmbeddedInDeclarator(false), IsFreeStanding(false), + IsCompleteDefinitionRequired(false), + NamedDeclOrQualifier((NamedDecl *)0) { assert((DK != Enum || TK == TTK_Enum) && "EnumDecl not matched with TTK_Enum"); - TagDeclKind = TK; - IsCompleteDefinition = false; - IsBeingDefined = false; - IsEmbeddedInDeclarator = false; - IsFreeStanding = false; - setPreviousDeclaration(PrevDecl); + setPreviousDecl(PrevDecl); } typedef Redeclarable<TagDecl> redeclarable_base; @@ -2492,6 +2591,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } @@ -2522,6 +2622,12 @@ public: return IsCompleteDefinition; } + /// \brief Return true if this complete decl is + /// required to be complete for some existing use. + bool isCompleteDefinitionRequired() const { + return IsCompleteDefinitionRequired; + } + /// isBeingDefined - Return true if this decl is currently being defined. bool isBeingDefined() const { return IsBeingDefined; @@ -2563,6 +2669,10 @@ public: void setCompleteDefinition(bool V) { IsCompleteDefinition = V; } + void setCompleteDefinitionRequired(bool V = true) { + IsCompleteDefinitionRequired = V; + } + // FIXME: Return StringRef; const char *getKindName() const { return TypeWithKeyword::getTagTypeKindName(getTagKind()); @@ -2599,11 +2709,22 @@ public: return (getDeclName() || getTypedefNameForAnonDecl()); } + bool hasDeclaratorForAnonDecl() const { + return dyn_cast_or_null<DeclaratorDecl>( + NamedDeclOrQualifier.get<NamedDecl *>()); + } + DeclaratorDecl *getDeclaratorForAnonDecl() const { + return hasExtInfo() ? 0 : dyn_cast_or_null<DeclaratorDecl>( + NamedDeclOrQualifier.get<NamedDecl *>()); + } + TypedefNameDecl *getTypedefNameForAnonDecl() const { - return hasExtInfo() ? 0 : - TypedefNameDeclOrQualifier.get<TypedefNameDecl*>(); + return hasExtInfo() ? 0 : dyn_cast_or_null<TypedefNameDecl>( + NamedDeclOrQualifier.get<NamedDecl *>()); } + void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; } + void setTypedefNameForAnonDecl(TypedefNameDecl *TDD); /// \brief Retrieve the nested-name-specifier that qualifies the name of this @@ -2702,21 +2823,22 @@ public: return cast<EnumDecl>(TagDecl::getCanonicalDecl()); } const EnumDecl *getCanonicalDecl() const { - return cast<EnumDecl>(TagDecl::getCanonicalDecl()); + return const_cast<EnumDecl*>(this)->getCanonicalDecl(); } - const EnumDecl *getPreviousDecl() const { - return cast_or_null<EnumDecl>(TagDecl::getPreviousDecl()); - } EnumDecl *getPreviousDecl() { - return cast_or_null<EnumDecl>(TagDecl::getPreviousDecl()); + return cast_or_null<EnumDecl>( + static_cast<TagDecl *>(this)->getPreviousDecl()); } - - const EnumDecl *getMostRecentDecl() const { - return cast<EnumDecl>(TagDecl::getMostRecentDecl()); + const EnumDecl *getPreviousDecl() const { + return const_cast<EnumDecl*>(this)->getPreviousDecl(); } + EnumDecl *getMostRecentDecl() { - return cast<EnumDecl>(TagDecl::getMostRecentDecl()); + return cast<EnumDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl()); + } + const EnumDecl *getMostRecentDecl() const { + return const_cast<EnumDecl*>(this)->getMostRecentDecl(); } EnumDecl *getDefinition() const { @@ -2912,18 +3034,19 @@ public: IdentifierInfo *Id, RecordDecl* PrevDecl = 0); static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); - const RecordDecl *getPreviousDecl() const { - return cast_or_null<RecordDecl>(TagDecl::getPreviousDecl()); - } RecordDecl *getPreviousDecl() { - return cast_or_null<RecordDecl>(TagDecl::getPreviousDecl()); + return cast_or_null<RecordDecl>( + static_cast<TagDecl *>(this)->getPreviousDecl()); } - - const RecordDecl *getMostRecentDecl() const { - return cast<RecordDecl>(TagDecl::getMostRecentDecl()); + const RecordDecl *getPreviousDecl() const { + return const_cast<RecordDecl*>(this)->getPreviousDecl(); } + RecordDecl *getMostRecentDecl() { - return cast<RecordDecl>(TagDecl::getMostRecentDecl()); + return cast<RecordDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl()); + } + const RecordDecl *getMostRecentDecl() const { + return const_cast<RecordDecl*>(this)->getMostRecentDecl(); } bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } @@ -3106,13 +3229,17 @@ private: Capture *Captures; unsigned NumCaptures; + unsigned ManglingNumber; + Decl *ManglingContextDecl; + protected: BlockDecl(DeclContext *DC, SourceLocation CaretLoc) : Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false), CapturesCXXThis(false), BlockMissingReturnType(true), IsConversionFromLambda(false), ParamInfo(0), NumParams(0), Body(0), - SignatureAsWritten(0), Captures(0), NumCaptures(0) {} + SignatureAsWritten(0), Captures(0), NumCaptures(0), + ManglingNumber(0), ManglingContextDecl(0) {} public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); @@ -3182,6 +3309,18 @@ public: const Capture *end, bool capturesCXXThis); + unsigned getBlockManglingNumber() const { + return ManglingNumber; + } + Decl *getBlockManglingContextDecl() const { + return ManglingContextDecl; + } + + void setBlockMangling(unsigned Number, Decl *Ctx) { + ManglingNumber = Number; + ManglingContextDecl = Ctx; + } + virtual SourceRange getSourceRange() const LLVM_READONLY; // Implement isa/cast/dyncast/etc. @@ -3354,7 +3493,7 @@ inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, } template<typename decl_type> -void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) { +void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { // Note: This routine is implemented here because we need both NamedDecl // and Redeclarable to be defined. @@ -3364,10 +3503,16 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) { // Point to previous. Make sure that this is actually the most recent // redeclaration, or we can build invalid chains. If the most recent // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. - First = PrevDecl->getFirstDeclaration(); + First = PrevDecl->getFirstDecl(); assert(First->RedeclLink.NextIsLatest() && "Expected first"); decl_type *MostRecent = First->RedeclLink.getNext(); RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent)); + + // If the declaration was previously visible, a redeclaration of it remains + // visible even if it wouldn't be visible by itself. + static_cast<decl_type*>(this)->IdentifierNamespace |= + MostRecent->getIdentifierNamespace() & + (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type); } else { // Make this first. First = static_cast<decl_type*>(this); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h b/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h index 5731308..3c5056c 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclAccessPair.h @@ -28,7 +28,7 @@ class NamedDecl; /// A POD class for pairing a NamedDecl* with an access specifier. /// Can be put into unions. class DeclAccessPair { - NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial + uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial enum { Mask = 0x3 }; @@ -40,10 +40,10 @@ public: } NamedDecl *getDecl() const { - return (NamedDecl*) (~Mask & (uintptr_t) Ptr); + return reinterpret_cast<NamedDecl*>(~Mask & Ptr); } AccessSpecifier getAccess() const { - return AccessSpecifier(Mask & (uintptr_t) Ptr); + return AccessSpecifier(Mask & Ptr); } void setDecl(NamedDecl *D) { @@ -53,8 +53,7 @@ public: set(getDecl(), AS); } void set(NamedDecl *D, AccessSpecifier AS) { - Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) | - reinterpret_cast<uintptr_t>(D)); + Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D); } operator NamedDecl*() const { return getDecl(); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h index 754facf..26eea64 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h @@ -16,6 +16,7 @@ #include "clang/AST/AttrIterator.h" #include "clang/AST/DeclarationName.h" +#include "clang/Basic/Linkage.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Compiler.h" @@ -31,6 +32,7 @@ class DeclarationName; class DependentDiagnostic; class EnumDecl; class FunctionDecl; +class LinkageComputer; class LinkageSpecDecl; class Module; class NamedDecl; @@ -157,7 +159,12 @@ public: /// This declaration is a C++ operator declared in a non-class /// context. All such operators are also in IDNS_Ordinary. /// C++ lexical operator lookup looks for these. - IDNS_NonMemberOperator = 0x0400 + IDNS_NonMemberOperator = 0x0400, + + /// This declaration is a function-local extern declaration of a + /// variable or function. This may also be IDNS_Ordinary if it + /// has been declared outside any function. + IDNS_LocalExtern = 0x0800 }; /// ObjCDeclQualifier - 'Qualifiers' written next to the return and @@ -284,19 +291,16 @@ protected: /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. unsigned IdentifierNamespace : 12; - /// \brief Whether the \c CachedLinkage field is active. - /// - /// This field is only valid for NamedDecls subclasses. - mutable unsigned HasCachedLinkage : 1; - - /// \brief If \c HasCachedLinkage, the linkage of this declaration. - /// - /// This field is only valid for NamedDecls subclasses. - mutable unsigned CachedLinkage : 2; + /// \brief If 0, we have not computed the linkage of this declaration. + /// Otherwise, it is the linkage + 1. + mutable unsigned CacheValidAndLinkage : 3; friend class ASTDeclWriter; friend class ASTDeclReader; friend class ASTReader; + friend class LinkageComputer; + + template<typename decl_type> friend class Redeclarable; private: void CheckAccessDeclContext() const; @@ -309,7 +313,7 @@ protected: HasAttrs(false), Implicit(false), Used(false), Referenced(false), Access(AS_none), FromASTFile(0), Hidden(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), - HasCachedLinkage(0) + CacheValidAndLinkage(0) { if (StatisticsEnabled) add(DK); } @@ -319,7 +323,7 @@ protected: HasAttrs(false), Implicit(false), Used(false), Referenced(false), Access(AS_none), FromASTFile(0), Hidden(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), - HasCachedLinkage(0) + CacheValidAndLinkage(0) { if (StatisticsEnabled) add(DK); } @@ -341,6 +345,18 @@ protected: /// \brief Update a potentially out-of-date declaration. void updateOutOfDate(IdentifierInfo &II) const; + Linkage getCachedLinkage() const { + return Linkage(CacheValidAndLinkage - 1); + } + + void setCachedLinkage(Linkage L) const { + CacheValidAndLinkage = L + 1; + } + + bool hasCachedLinkage() const { + return CacheValidAndLinkage; + } + public: /// \brief Source range that this declaration covers. @@ -419,7 +435,6 @@ public: return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs()); } const AttrVec &getAttrs() const; - void swapAttrs(Decl *D); void dropAttrs(); void addAttr(Attr *A) { @@ -490,7 +505,16 @@ public: /// whether the function is used. bool isUsed(bool CheckUsedAttr = true) const; - void setUsed(bool U = true) { Used = U; } + /// \brief Set whether the declaration is used, in the sense of odr-use. + /// + /// This should only be used immediately after creating a declaration. + void setIsUsed() { Used = true; } + + /// \brief Mark the declaration used, in the sense of odr-use. + /// + /// This notifies any mutation listeners in addition to setting a bit + /// indicating the declaration is used. + void markUsed(ASTContext &C); /// \brief Whether this declaration was referenced. bool isReferenced() const; @@ -513,13 +537,13 @@ public: NextInContextAndBits.setInt(Bits); } -protected: /// \brief Whether this declaration was marked as being private to the /// module in which it was defined. - bool isModulePrivate() const { + bool isModulePrivate() const { return NextInContextAndBits.getInt() & ModulePrivateFlag; } - + +protected: /// \brief Specify whether this declaration was marked as being private /// to the module in which it was defined. void setModulePrivate(bool MP = true) { @@ -761,7 +785,12 @@ public: const Decl *getPreviousDecl() const { return const_cast<Decl *>(this)->getPreviousDeclImpl(); } - + + /// \brief True if this is the first declaration in its redeclaration chain. + bool isFirstDecl() const { + return getPreviousDecl() == 0; + } + /// \brief Retrieve the most recent declaration that declares the same entity /// as this declaration (which may be this declaration). Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); } @@ -777,8 +806,10 @@ public: /// top-level Stmt* of that body. Otherwise this method returns null. virtual Stmt* getBody() const { return 0; } - /// \brief Returns true if this Decl represents a declaration for a body of + /// \brief Returns true if this \c Decl represents a declaration for a body of /// code, such as a function or method definition. + /// Note that \c hasBody can also return true if any redeclaration of this + /// \c Decl represents a declaration for a body of code. virtual bool hasBody() const { return getBody() != 0; } /// getBodyRBrace - Gets the right brace of the body, if a body exists. @@ -808,37 +839,71 @@ public: bool isFunctionOrFunctionTemplate() const; /// \brief Changes the namespace of this declaration to reflect that it's + /// a function-local extern declaration. + /// + /// These declarations appear in the lexical context of the extern + /// declaration, but in the semantic context of the enclosing namespace + /// scope. + void setLocalExternDecl() { + assert((IdentifierNamespace == IDNS_Ordinary || + IdentifierNamespace == IDNS_OrdinaryFriend) && + "namespace is not ordinary"); + + Decl *Prev = getPreviousDecl(); + IdentifierNamespace &= ~IDNS_Ordinary; + + IdentifierNamespace |= IDNS_LocalExtern; + if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary) + IdentifierNamespace |= IDNS_Ordinary; + } + + /// \brief Determine whether this is a block-scope declaration with linkage. + /// This will either be a local variable declaration declared 'extern', or a + /// local function declaration. + bool isLocalExternDecl() { + return IdentifierNamespace & IDNS_LocalExtern; + } + + /// \brief Changes the namespace of this declaration to reflect that it's /// the object of a friend declaration. /// /// These declarations appear in the lexical context of the friending /// class, but in the semantic context of the actual entity. This property /// applies only to a specific decl object; other redeclarations of the /// same entity may not (and probably don't) share this property. - void setObjectOfFriendDecl(bool PreviouslyDeclared) { + void setObjectOfFriendDecl(bool PerformFriendInjection = false) { unsigned OldNS = IdentifierNamespace; assert((OldNS & (IDNS_Tag | IDNS_Ordinary | - IDNS_TagFriend | IDNS_OrdinaryFriend)) && + IDNS_TagFriend | IDNS_OrdinaryFriend | + IDNS_LocalExtern)) && "namespace includes neither ordinary nor tag"); assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | - IDNS_TagFriend | IDNS_OrdinaryFriend)) && + IDNS_TagFriend | IDNS_OrdinaryFriend | + IDNS_LocalExtern)) && "namespace includes other than ordinary or tag"); - IdentifierNamespace = 0; + Decl *Prev = getPreviousDecl(); + IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type); + if (OldNS & (IDNS_Tag | IDNS_TagFriend)) { IdentifierNamespace |= IDNS_TagFriend; - if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Tag | IDNS_Type; + if (PerformFriendInjection || + (Prev && Prev->getIdentifierNamespace() & IDNS_Tag)) + IdentifierNamespace |= IDNS_Tag | IDNS_Type; } - if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) { + if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) { IdentifierNamespace |= IDNS_OrdinaryFriend; - if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Ordinary; + if (PerformFriendInjection || + (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)) + IdentifierNamespace |= IDNS_Ordinary; } } enum FriendObjectKind { - FOK_None, // not a friend object - FOK_Declared, // a friend of a previously-declared entity - FOK_Undeclared // a friend of a previously-undeclared entity + FOK_None, ///< Not a friend object. + FOK_Declared, ///< A friend of a previously-declared entity. + FOK_Undeclared ///< A friend of a previously-undeclared entity. }; /// \brief Determines whether this declaration is the object of a @@ -846,11 +911,11 @@ public: /// /// There is currently no direct way to find the associated FriendDecl. FriendObjectKind getFriendObjectKind() const { - unsigned mask - = (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend)); + unsigned mask = + (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend)); if (!mask) return FOK_None; - return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? - FOK_Declared : FOK_Undeclared); + return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? FOK_Declared + : FOK_Undeclared); } /// Specifies that this declaration is a C++ overloaded non-member. @@ -877,9 +942,6 @@ public: // Same as dump(), but forces color printing. LLVM_ATTRIBUTE_USED void dumpColor() const; void dump(raw_ostream &Out) const; - // Debuggers don't usually respect default arguments. - LLVM_ATTRIBUTE_USED void dumpXML() const; - void dumpXML(raw_ostream &OS) const; private: void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx); @@ -974,6 +1036,7 @@ protected: mutable Decl *LastDecl; friend class ExternalASTSource; + friend class ASTDeclReader; friend class ASTWriter; /// \brief Build up a chain of declarations. @@ -1096,6 +1159,14 @@ public: /// C++0x scoped enums), and C++ linkage specifications. bool isTransparentContext() const; + /// \brief Determines whether this context or some of its ancestors is a + /// linkage specification context that specifies C linkage. + bool isExternCContext() const; + + /// \brief Determines whether this context or some of its ancestors is a + /// linkage specification context that specifies C++ linkage. + bool isExternCXXContext() const; + /// \brief Determine whether this declaration context is equivalent /// to the declaration context DC. bool Equals(const DeclContext *DC) const { @@ -1429,12 +1500,20 @@ public: return const_cast<DeclContext*>(this)->lookup(Name); } + /// \brief Find the declarations with the given name that are visible + /// within this context; don't attempt to retrieve anything from an + /// external source. + lookup_result noload_lookup(DeclarationName Name); + /// \brief A simplistic name lookup mechanism that performs name lookup /// into this declaration context without consulting the external source. /// /// This function should almost never be used, because it subverts the /// usual relationship between a DeclContext and the external source. /// See the ASTImporter for the (few, but important) use cases. + /// + /// FIXME: This is very inefficient; replace uses of it with uses of + /// noload_lookup. void localUncachedLookup(DeclarationName Name, SmallVectorImpl<NamedDecl *> &Results); @@ -1458,10 +1537,16 @@ public: /// of looking up every possible name. class all_lookups_iterator; + /// \brief Iterators over all possible lookups within this context. all_lookups_iterator lookups_begin() const; - all_lookups_iterator lookups_end() const; + /// \brief Iterators over all possible lookups within this context that are + /// currently loaded; don't attempt to retrieve anything from an external + /// source. + all_lookups_iterator noload_lookups_begin() const; + all_lookups_iterator noload_lookups_end() const; + /// udir_iterator - Iterates through the using-directives stored /// within this context. typedef UsingDirectiveDecl * const * udir_iterator; @@ -1532,6 +1617,8 @@ public: static bool classof(const DeclContext *D) { return true; } LLVM_ATTRIBUTE_USED void dumpDeclContext() const; + LLVM_ATTRIBUTE_USED void dumpLookups() const; + LLVM_ATTRIBUTE_USED void dumpLookups(llvm::raw_ostream &OS) const; private: void reconcileExternalVisibleStorage(); @@ -1548,6 +1635,8 @@ private: friend class DependentDiagnostic; StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; + template<decl_iterator (DeclContext::*Begin)() const, + decl_iterator (DeclContext::*End)() const> void buildLookupImpl(DeclContext *DCtx); void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, bool Rediscoverable); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h index c483dde..dbc4132 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h @@ -6,10 +6,11 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the C++ Decl subclasses, other than those for -// templates (in DeclTemplate.h) and friends (in DeclFriend.h). -// +/// +/// \file +/// \brief Defines the C++ Decl subclasses, other than those for templates +/// (found in DeclTemplate.h) and friends (in DeclFriend.h). +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_DECLCXX_H @@ -88,7 +89,7 @@ namespace llvm { namespace clang { -/// @brief Represents an access specifier followed by colon ':'. +/// \brief Represents an access specifier followed by colon ':'. /// /// An objects of this class represents sugar for the syntactic occurrence /// of an access specifier followed by a colon in the list of member @@ -146,16 +147,16 @@ public: /// level of access (public, protected, private) is used for the /// derivation. For example: /// -/// @code +/// \code /// class A { }; /// class B { }; /// class C : public virtual A, protected B { }; -/// @endcode +/// \endcode /// /// In this code, C will have two CXXBaseSpecifiers, one for "public /// virtual A" and the other for "protected B". class CXXBaseSpecifier { - /// Range - The source code range that covers the full base + /// \brief The source code range that covers the full base /// specifier, including the "virtual" (if present) and access /// specifier (if present). SourceRange Range; @@ -167,25 +168,26 @@ class CXXBaseSpecifier { /// \brief Whether this is a virtual base class or not. bool Virtual : 1; - /// BaseOfClass - Whether this is the base of a class (true) or of a - /// struct (false). This determines the mapping from the access - /// specifier as written in the source code to the access specifier - /// used for semantic analysis. + /// \brief Whether this is the base of a class (true) or of a struct (false). + /// + /// This determines the mapping from the access specifier as written in the + /// source code to the access specifier used for semantic analysis. bool BaseOfClass : 1; - /// Access - Access specifier as written in the source code (which - /// may be AS_none). The actual type of data stored here is an - /// AccessSpecifier, but we use "unsigned" here to work around a - /// VC++ bug. + /// \brief Access specifier as written in the source code (may be AS_none). + /// + /// The actual type of data stored here is an AccessSpecifier, but we use + /// "unsigned" here to work around a VC++ bug. unsigned Access : 2; - /// InheritConstructors - Whether the class contains a using declaration + /// \brief Whether the class contains a using declaration /// to inherit the named class's constructors. bool InheritConstructors : 1; - /// BaseTypeInfo - The type of the base class. This will be a class or struct - /// (or a typedef of such). The source code range does not include the - /// "virtual" or access specifier. + /// \brief The type of the base class. + /// + /// This will be a class or struct (or a typedef of such). The source code + /// range does not include the \c virtual or the access specifier. TypeSourceInfo *BaseTypeInfo; public: @@ -196,14 +198,12 @@ public: : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC), Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { } - /// getSourceRange - Retrieves the source range that contains the - /// entire base specifier. + /// \brief Retrieves the source range that contains the entire base specifier. SourceRange getSourceRange() const LLVM_READONLY { return Range; } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } - /// isVirtual - Determines whether the base class is a virtual base - /// class (or not). + /// \brief Determines whether the base class is a virtual base class (or not). bool isVirtual() const { return Virtual; } /// \brief Determine whether this base class is a base of a class declared @@ -226,11 +226,11 @@ public: return EllipsisLoc; } - /// getAccessSpecifier - Returns the access specifier for this base - /// specifier. This is the actual base specifier as used for - /// semantic analysis, so the result can never be AS_none. To - /// retrieve the access specifier as written in the source code, use - /// getAccessSpecifierAsWritten(). + /// \brief Returns the access specifier for this base specifier. + /// + /// This is the actual base specifier as used for semantic analysis, so + /// the result can never be AS_none. To retrieve the access specifier as + /// written in the source code, use getAccessSpecifierAsWritten(). AccessSpecifier getAccessSpecifier() const { if ((AccessSpecifier)Access == AS_none) return BaseOfClass? AS_private : AS_public; @@ -238,19 +238,23 @@ public: return (AccessSpecifier)Access; } - /// getAccessSpecifierAsWritten - Retrieves the access specifier as - /// written in the source code (which may mean that no access - /// specifier was explicitly written). Use getAccessSpecifier() to - /// retrieve the access specifier for use in semantic analysis. + /// \brief Retrieves the access specifier as written in the source code + /// (which may mean that no access specifier was explicitly written). + /// + /// Use getAccessSpecifier() to retrieve the access specifier for use in + /// semantic analysis. AccessSpecifier getAccessSpecifierAsWritten() const { return (AccessSpecifier)Access; } - /// getType - Retrieves the type of the base class. This type will - /// always be an unqualified class type. - QualType getType() const { return BaseTypeInfo->getType(); } + /// \brief Retrieves the type of the base class. + /// + /// This type will always be an unqualified class type. + QualType getType() const { + return BaseTypeInfo->getType().getUnqualifiedType(); + } - /// getTypeLoc - Retrieves the type and source location of the base class. + /// \brief Retrieves the type and source location of the base class. TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; } }; @@ -264,7 +268,8 @@ enum MSInheritanceModel { MSIM_Unspecified }; -/// CXXRecordDecl - Represents a C++ struct/union/class. +/// \brief Represents a C++ struct/union/class. +/// /// FIXME: This class will disappear once we've properly taught RecordDecl /// to deal with C++-specific things. class CXXRecordDecl : public RecordDecl { @@ -288,32 +293,32 @@ class CXXRecordDecl : public RecordDecl { /// \brief True if this class has any user-declared constructors. bool UserDeclaredConstructor : 1; - /// The user-declared special members which this class has. + /// \brief The user-declared special members which this class has. unsigned UserDeclaredSpecialMembers : 6; - /// Aggregate - True when this class is an aggregate. + /// \brief True when this class is an aggregate. bool Aggregate : 1; - /// PlainOldData - True when this class is a POD-type. + /// \brief True when this class is a POD-type. bool PlainOldData : 1; - /// Empty - true when this class is empty for traits purposes, + /// true when this class is empty for traits purposes, /// i.e. has no data members other than 0-width bit-fields, has no /// virtual function/base, and doesn't inherit from a non-empty /// class. Doesn't take union-ness into account. bool Empty : 1; - /// Polymorphic - True when this class is polymorphic, i.e. has at + /// \brief True when this class is polymorphic, i.e., has at /// least one virtual member or derives from a polymorphic class. bool Polymorphic : 1; - /// Abstract - True when this class is abstract, i.e. has at least + /// \brief True when this class is abstract, i.e., has at least /// one pure virtual function, (that can come from a base class). bool Abstract : 1; - /// IsStandardLayout - True when this class has standard layout. + /// \brief True when this class has standard layout. /// - /// C++0x [class]p7. A standard-layout class is a class that: + /// C++11 [class]p7. A standard-layout class is a class that: /// * has no non-static data members of type non-standard-layout class (or /// array of such types) or reference, /// * has no virtual functions (10.3) and no virtual base classes (10.1), @@ -327,20 +332,19 @@ class CXXRecordDecl : public RecordDecl { /// member. bool IsStandardLayout : 1; - /// HasNoNonEmptyBases - True when there are no non-empty base classes. + /// \brief True when there are no non-empty base classes. /// /// This is a helper bit of state used to implement IsStandardLayout more /// efficiently. bool HasNoNonEmptyBases : 1; - /// HasPrivateFields - True when there are private non-static data members. + /// \brief True when there are private non-static data members. bool HasPrivateFields : 1; - /// HasProtectedFields - True when there are protected non-static data - /// members. + /// \brief True when there are protected non-static data members. bool HasProtectedFields : 1; - /// HasPublicFields - True when there are private non-static data members. + /// \brief True when there are private non-static data members. bool HasPublicFields : 1; /// \brief True if this class (or any subobject) has mutable fields. @@ -353,8 +357,10 @@ class CXXRecordDecl : public RecordDecl { bool HasInClassInitializer : 1; /// \brief True if any field is of reference type, and does not have an - /// in-class initializer. In this case, value-initialization of this class - /// is illegal in C++98 even if the class has a trivial default constructor. + /// in-class initializer. + /// + /// In this case, value-initialization of this class is illegal in C++98 + /// even if the class has a trivial default constructor. bool HasUninitializedReferenceMember : 1; /// \brief These flags are \c true if a defaulted corresponding special @@ -389,30 +395,29 @@ class CXXRecordDecl : public RecordDecl { /// members which have not yet been declared. unsigned DeclaredNonTrivialSpecialMembers : 6; - /// HasIrrelevantDestructor - True when this class has a destructor with no - /// semantic effect. + /// \brief True when this class has a destructor with no semantic effect. bool HasIrrelevantDestructor : 1; - /// HasConstexprNonCopyMoveConstructor - True when this class has at least - /// one user-declared constexpr constructor which is neither the copy nor - /// move constructor. + /// \brief True when this class has at least one user-declared constexpr + /// constructor which is neither the copy nor move constructor. bool HasConstexprNonCopyMoveConstructor : 1; - /// DefaultedDefaultConstructorIsConstexpr - True if a defaulted default - /// constructor for this class would be constexpr. + /// \brief True if a defaulted default constructor for this class would + /// be constexpr. bool DefaultedDefaultConstructorIsConstexpr : 1; - /// HasConstexprDefaultConstructor - True if this class has a constexpr - /// default constructor (either user-declared or implicitly declared). + /// \brief True if this class has a constexpr default constructor. + /// + /// This is true for either a user-declared constexpr default constructor + /// or an implicitly declared constexpr default constructor.. bool HasConstexprDefaultConstructor : 1; - /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least - /// one non-static data member or base class of non-literal or volatile - /// type. + /// \brief True when this class contains at least one non-static data + /// member or base class of non-literal or volatile type. bool HasNonLiteralTypeFieldsOrBases : 1; - /// ComputedVisibleConversions - True when visible conversion functions are - /// already computed and are available. + /// \brief True when visible conversion functions are already computed + /// and are available. bool ComputedVisibleConversions : 1; /// \brief Whether we have a C++11 user-provided default constructor (not @@ -439,50 +444,44 @@ class CXXRecordDecl : public RecordDecl { /// const-qualified reference parameter or a non-reference parameter. bool HasDeclaredCopyAssignmentWithConstParam : 1; - /// \brief Whether an implicit move constructor was attempted to be declared - /// but would have been deleted. - bool FailedImplicitMoveConstructor : 1; - - /// \brief Whether an implicit move assignment operator was attempted to be - /// declared but would have been deleted. - bool FailedImplicitMoveAssignment : 1; - /// \brief Whether this class describes a C++ lambda. bool IsLambda : 1; - /// NumBases - The number of base class specifiers in Bases. + /// \brief The number of base class specifiers in Bases. unsigned NumBases; - /// NumVBases - The number of virtual base class specifiers in VBases. + /// \brief The number of virtual base class specifiers in VBases. unsigned NumVBases; - /// Bases - Base classes of this class. + /// \brief Base classes of this class. + /// /// FIXME: This is wasted space for a union. LazyCXXBaseSpecifiersPtr Bases; - /// VBases - direct and indirect virtual base classes of this class. + /// \brief direct and indirect virtual base classes of this class. LazyCXXBaseSpecifiersPtr VBases; - /// Conversions - Overload set containing the conversion functions - /// of this C++ class (but not its inherited conversion - /// functions). Each of the entries in this overload set is a - /// CXXConversionDecl. - ASTUnresolvedSet Conversions; + /// \brief The conversion functions of this C++ class (but not its + /// inherited conversion functions). + /// + /// Each of the entries in this overload set is a CXXConversionDecl. + LazyASTUnresolvedSet Conversions; - /// VisibleConversions - Overload set containing the conversion - /// functions of this C++ class and all those inherited conversion - /// functions that are visible in this class. Each of the entries - /// in this overload set is a CXXConversionDecl or a + /// \brief The conversion functions of this C++ class and all those + /// inherited conversion functions that are visible in this class. + /// + /// Each of the entries in this overload set is a CXXConversionDecl or a /// FunctionTemplateDecl. - ASTUnresolvedSet VisibleConversions; + LazyASTUnresolvedSet VisibleConversions; - /// Definition - The declaration which defines this record. + /// \brief The declaration which defines this record. CXXRecordDecl *Definition; - /// FirstFriend - The first friend declaration in this class, or - /// null if there aren't any. This is actually currently stored - /// in reverse order. - FriendDecl *FirstFriend; + /// \brief The first friend declaration in this class, or null if there + /// aren't any. + /// + /// This is actually currently stored in reverse order. + LazyDeclPtr FirstFriend; /// \brief Retrieve the set of direct base classes. CXXBaseSpecifier *getBases() const { @@ -507,10 +506,12 @@ class CXXRecordDecl : public RecordDecl { struct LambdaDefinitionData : public DefinitionData { typedef LambdaExpr::Capture Capture; - LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent) - : DefinitionData(D), Dependent(Dependent), NumCaptures(0), - NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0), - MethodTyInfo(Info) + LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, + bool Dependent, bool IsGeneric, + LambdaCaptureDefault CaptureDefault) + : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), + CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), + ManglingNumber(0), ContextDecl(0), Captures(0), MethodTyInfo(Info) { IsLambda = true; } @@ -522,14 +523,20 @@ class CXXRecordDecl : public RecordDecl { /// within the default argument of a function template, because the /// lambda will have been created with the enclosing context as its /// declaration context, rather than function. This is an unfortunate - /// artifact of having to parse the default arguments before + /// artifact of having to parse the default arguments before. unsigned Dependent : 1; - /// \brief The number of captures in this lambda. - unsigned NumCaptures : 16; + /// \brief Whether this lambda is a generic lambda. + unsigned IsGenericLambda : 1; + + /// \brief The Default Capture. + unsigned CaptureDefault : 2; + + /// \brief The number of captures in this lambda is limited 2^NumCaptures. + unsigned NumCaptures : 15; /// \brief The number of explicit captures in this lambda. - unsigned NumExplicitCaptures : 15; + unsigned NumExplicitCaptures : 13; /// \brief The number used to indicate this lambda expression for name /// mangling in the Itanium C++ ABI. @@ -547,6 +554,7 @@ class CXXRecordDecl : public RecordDecl { /// \brief The type of the call method. TypeSourceInfo *MethodTyInfo; + }; struct DefinitionData &data() { @@ -569,7 +577,7 @@ class CXXRecordDecl : public RecordDecl { /// \brief The template or declaration that this declaration /// describes or was instantiated from, respectively. /// - /// For non-templates, this value will be NULL. For record + /// For non-templates, this value will be null. For record /// declarations that describe a class template, this will be a /// pointer to a ClassTemplateDecl. For member /// classes of class template specializations, this will be the @@ -597,27 +605,29 @@ class CXXRecordDecl : public RecordDecl { friend class ASTNodeImporter; + /// \brief Get the head of our list of friend declarations, possibly + /// deserializing the friends from an external AST source. + FriendDecl *getFirstFriend() const; + protected: CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl); public: - /// base_class_iterator - Iterator that traverses the base classes - /// of a class. + /// \brief Iterator that traverses the base classes of a class. typedef CXXBaseSpecifier* base_class_iterator; - /// base_class_const_iterator - Iterator that traverses the base - /// classes of a class. + /// \brief Iterator that traverses the base classes of a class. typedef const CXXBaseSpecifier* base_class_const_iterator; - /// reverse_base_class_iterator = Iterator that traverses the base classes - /// of a class in reverse order. + /// \brief Iterator that traverses the base classes of a class in reverse + /// order. typedef std::reverse_iterator<base_class_iterator> reverse_base_class_iterator; - /// reverse_base_class_iterator = Iterator that traverses the base classes - /// of a class in reverse order. + /// \brief Iterator that traverses the base classes of a class in reverse + /// order. typedef std::reverse_iterator<base_class_const_iterator> reverse_base_class_const_iterator; @@ -628,18 +638,21 @@ public: return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl()); } + CXXRecordDecl *getPreviousDecl() { + return cast_or_null<CXXRecordDecl>( + static_cast<RecordDecl *>(this)->getPreviousDecl()); + } const CXXRecordDecl *getPreviousDecl() const { - return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDecl()); + return const_cast<CXXRecordDecl*>(this)->getPreviousDecl(); } - CXXRecordDecl *getPreviousDecl() { - return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDecl()); + + CXXRecordDecl *getMostRecentDecl() { + return cast<CXXRecordDecl>( + static_cast<RecordDecl *>(this)->getMostRecentDecl()); } const CXXRecordDecl *getMostRecentDecl() const { - return cast_or_null<CXXRecordDecl>(RecordDecl::getMostRecentDecl()); - } - CXXRecordDecl *getMostRecentDecl() { - return cast_or_null<CXXRecordDecl>(RecordDecl::getMostRecentDecl()); + return const_cast<CXXRecordDecl*>(this)->getMostRecentDecl(); } CXXRecordDecl *getDefinition() const { @@ -655,18 +668,18 @@ public: bool DelayTypeCreation = false); static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC, TypeSourceInfo *Info, SourceLocation Loc, - bool DependentLambda); + bool DependentLambda, bool IsGeneric, + LambdaCaptureDefault CaptureDefault); static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); bool isDynamicClass() const { return data().Polymorphic || data().NumVBases != 0; } - /// setBases - Sets the base classes of this struct or class. + /// \brief Sets the base classes of this struct or class. void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases); - /// getNumBases - Retrieves the number of base classes of this - /// class. + /// \brief Retrieves the number of base classes of this class. unsigned getNumBases() const { return data().NumBases; } base_class_iterator bases_begin() { return data().getBases(); } @@ -688,8 +701,7 @@ public: return reverse_base_class_const_iterator(bases_begin()); } - /// getNumVBases - Retrieves the number of virtual base classes of this - /// class. + /// \brief Retrieves the number of virtual base classes of this class. unsigned getNumVBases() const { return data().NumVBases; } base_class_iterator vbases_begin() { return data().getVBases(); } @@ -720,12 +732,12 @@ public: /// special methods, etc. typedef specific_decl_iterator<CXXMethodDecl> method_iterator; - /// method_begin - Method begin iterator. Iterates in the order the methods + /// \brief Method begin iterator. Iterates in the order the methods /// were declared. method_iterator method_begin() const { return method_iterator(decls_begin()); } - /// method_end - Method end iterator. + /// \brief Method past-the-end iterator. method_iterator method_end() const { return method_iterator(decls_end()); } @@ -749,18 +761,20 @@ public: /// Determines whether this record has any friends. bool hasFriends() const { - return data().FirstFriend != 0; + return data().FirstFriend.isValid(); } /// \brief \c true if we know for sure that this class has a single, /// accessible, unambiguous move constructor that is not deleted. bool hasSimpleMoveConstructor() const { - return !hasUserDeclaredMoveConstructor() && hasMoveConstructor(); + return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() && + !data().DefaultedMoveConstructorIsDeleted; } /// \brief \c true if we know for sure that this class has a single, /// accessible, unambiguous move assignment operator that is not deleted. bool hasSimpleMoveAssignment() const { - return !hasUserDeclaredMoveAssignment() && hasMoveAssignment(); + return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() && + !data().DefaultedMoveAssignmentIsDeleted; } /// \brief \c true if we know for sure that this class has an accessible /// destructor that is not deleted. @@ -784,22 +798,22 @@ public: !(data().DeclaredSpecialMembers & SMF_DefaultConstructor); } - /// hasUserDeclaredConstructor - Whether this class has any - /// user-declared constructors. When true, a default constructor - /// will not be implicitly declared. + /// \brief Determine whether this class has any user-declared constructors. + /// + /// When true, a default constructor will not be implicitly declared. bool hasUserDeclaredConstructor() const { return data().UserDeclaredConstructor; } - /// hasUserProvidedDefaultconstructor - Whether this class has a - /// user-provided default constructor per C++0x. + /// \brief Whether this class has a user-provided default constructor + /// per C++11. bool hasUserProvidedDefaultConstructor() const { return data().UserProvidedDefaultConstructor; } - /// hasUserDeclaredCopyConstructor - Whether this class has a - /// user-declared copy constructor. When false, a copy constructor - /// will be implicitly declared. + /// \brief Determine whether this class has a user-declared copy constructor. + /// + /// When false, a copy constructor will be implicitly declared. bool hasUserDeclaredCopyConstructor() const { return data().UserDeclaredSpecialMembers & SMF_CopyConstructor; } @@ -830,9 +844,11 @@ public: implicitCopyConstructorHasConstParam()); } - /// hasUserDeclaredMoveOperation - Whether this class has a user- - /// declared move constructor or assignment operator. When false, a - /// move constructor and assignment operator may be implicitly declared. + /// \brief Whether this class has a user-declared move constructor or + /// assignment operator. + /// + /// When false, a move constructor and assignment operator may be + /// implicitly declared. bool hasUserDeclaredMoveOperation() const { return data().UserDeclaredSpecialMembers & (SMF_MoveConstructor | SMF_MoveAssignment); @@ -850,28 +866,23 @@ public: needsImplicitMoveConstructor(); } - /// \brief Determine whether implicit move constructor generation for this - /// class has failed before. - bool hasFailedImplicitMoveConstructor() const { - return data().FailedImplicitMoveConstructor; - } - - /// \brief Set whether implicit move constructor generation for this class - /// has failed before. - void setFailedImplicitMoveConstructor(bool Failed = true) { - data().FailedImplicitMoveConstructor = Failed; + /// \brief Set that we attempted to declare an implicitly move + /// constructor, but overload resolution failed so we deleted it. + void setImplicitMoveConstructorIsDeleted() { + assert((data().DefaultedMoveConstructorIsDeleted || + needsOverloadResolutionForMoveConstructor()) && + "move constructor should not be deleted"); + data().DefaultedMoveConstructorIsDeleted = true; } /// \brief Determine whether this class should get an implicit move /// constructor or if any existing special member function inhibits this. bool needsImplicitMoveConstructor() const { - return !hasFailedImplicitMoveConstructor() && - !(data().DeclaredSpecialMembers & SMF_MoveConstructor) && + return !(data().DeclaredSpecialMembers & SMF_MoveConstructor) && !hasUserDeclaredCopyConstructor() && !hasUserDeclaredCopyAssignment() && !hasUserDeclaredMoveAssignment() && - !hasUserDeclaredDestructor() && - !data().DefaultedMoveConstructorIsDeleted; + !hasUserDeclaredDestructor(); } /// \brief Determine whether we need to eagerly declare a defaulted move @@ -880,9 +891,10 @@ public: return data().NeedOverloadResolutionForMoveConstructor; } - /// hasUserDeclaredCopyAssignment - Whether this class has a - /// user-declared copy assignment operator. When false, a copy - /// assigment operator will be implicitly declared. + /// \brief Determine whether this class has a user-declared copy assignment + /// operator. + /// + /// When false, a copy assigment operator will be implicitly declared. bool hasUserDeclaredCopyAssignment() const { return data().UserDeclaredSpecialMembers & SMF_CopyAssignment; } @@ -907,7 +919,7 @@ public: /// \brief Determine whether this class has a copy assignment operator with /// a parameter type which is a reference to a const-qualified type or is not - /// a reference.. + /// a reference. bool hasCopyAssignmentWithConstParam() const { return data().HasDeclaredCopyAssignmentWithConstParam || (needsImplicitCopyAssignment() && @@ -926,29 +938,24 @@ public: needsImplicitMoveAssignment(); } - /// \brief Determine whether implicit move assignment generation for this - /// class has failed before. - bool hasFailedImplicitMoveAssignment() const { - return data().FailedImplicitMoveAssignment; - } - - /// \brief Set whether implicit move assignment generation for this class - /// has failed before. - void setFailedImplicitMoveAssignment(bool Failed = true) { - data().FailedImplicitMoveAssignment = Failed; + /// \brief Set that we attempted to declare an implicit move assignment + /// operator, but overload resolution failed so we deleted it. + void setImplicitMoveAssignmentIsDeleted() { + assert((data().DefaultedMoveAssignmentIsDeleted || + needsOverloadResolutionForMoveAssignment()) && + "move assignment should not be deleted"); + data().DefaultedMoveAssignmentIsDeleted = true; } /// \brief Determine whether this class should get an implicit move /// assignment operator or if any existing special member function inhibits /// this. bool needsImplicitMoveAssignment() const { - return !hasFailedImplicitMoveAssignment() && - !(data().DeclaredSpecialMembers & SMF_MoveAssignment) && + return !(data().DeclaredSpecialMembers & SMF_MoveAssignment) && !hasUserDeclaredCopyConstructor() && !hasUserDeclaredCopyAssignment() && !hasUserDeclaredMoveConstructor() && - !hasUserDeclaredDestructor() && - !data().DefaultedMoveAssignmentIsDeleted; + !hasUserDeclaredDestructor(); } /// \brief Determine whether we need to eagerly declare a move assignment @@ -957,9 +964,9 @@ public: return data().NeedOverloadResolutionForMoveAssignment; } - /// hasUserDeclaredDestructor - Whether this class has a - /// user-declared destructor. When false, a destructor will be - /// implicitly declared. + /// \brief Determine whether this class has a user-declared destructor. + /// + /// When false, a destructor will be implicitly declared. bool hasUserDeclaredDestructor() const { return data().UserDeclaredSpecialMembers & SMF_Destructor; } @@ -979,15 +986,42 @@ public: /// \brief Determine whether this class describes a lambda function object. bool isLambda() const { return hasDefinition() && data().IsLambda; } + /// \brief Determine whether this class describes a generic + /// lambda function object (i.e. function call operator is + /// a template). + bool isGenericLambda() const; + + /// \brief Retrieve the lambda call operator of the closure type + /// if this is a closure type. + CXXMethodDecl *getLambdaCallOperator() const; + + /// \brief Retrieve the lambda static invoker, the address of which + /// is returned by the conversion operator, and the body of which + /// is forwarded to the lambda call operator. + CXXMethodDecl *getLambdaStaticInvoker() const; + + /// \brief Retrieve the generic lambda's template parameter list. + /// Returns null if the class does not represent a lambda or a generic + /// lambda. + TemplateParameterList *getGenericLambdaTemplateParameterList() const; + + LambdaCaptureDefault getLambdaCaptureDefault() const { + assert(isLambda()); + return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault); + } + /// \brief For a closure type, retrieve the mapping from captured - /// variables and this to the non-static data members that store the + /// variables and \c this to the non-static data members that store the /// values or references of the captures. /// /// \param Captures Will be populated with the mapping from captured /// variables to the corresponding fields. /// /// \param ThisCapture Will be set to the field declaration for the - /// 'this' capture. + /// \c this capture. + /// + /// \note No entries will be added for init-captures, as they do not capture + /// variables. void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures, FieldDecl *&ThisCapture) const; @@ -1001,10 +1035,10 @@ public: typedef UnresolvedSetIterator conversion_iterator; conversion_iterator conversion_begin() const { - return data().Conversions.begin(); + return data().Conversions.get(getASTContext()).begin(); } conversion_iterator conversion_end() const { - return data().Conversions.end(); + return data().Conversions.get(getASTContext()).end(); } /// Removes a conversion function from this class. The conversion @@ -1012,38 +1046,39 @@ public: /// this class must currently be in the process of being defined. void removeConversion(const NamedDecl *Old); - /// getVisibleConversionFunctions - get all conversion functions visible - /// in current class; including conversion function templates. + /// \brief Get all conversion functions visible in current class, + /// including conversion function templates. std::pair<conversion_iterator, conversion_iterator> getVisibleConversionFunctions(); - /// isAggregate - Whether this class is an aggregate (C++ - /// [dcl.init.aggr]), which is a class with no user-declared - /// constructors, no private or protected non-static data members, - /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1). + /// Determine whether this class is an aggregate (C++ [dcl.init.aggr]), + /// which is a class with no user-declared constructors, no private + /// or protected non-static data members, no base classes, and no virtual + /// functions (C++ [dcl.init.aggr]p1). bool isAggregate() const { return data().Aggregate; } - /// hasInClassInitializer - Whether this class has any in-class initializers + /// \brief Whether this class has any in-class initializers /// for non-static data members. bool hasInClassInitializer() const { return data().HasInClassInitializer; } /// \brief Whether this class or any of its subobjects has any members of - /// reference type which would make value-initialization ill-formed, per - /// C++03 [dcl.init]p5: - /// -- if T is a non-union class type without a user-declared constructor, - /// then every non-static data member and base-class component of T is - /// value-initialized - /// [...] - /// A program that calls for [...] value-initialization of an entity of - /// reference type is ill-formed. + /// reference type which would make value-initialization ill-formed. + /// + /// Per C++03 [dcl.init]p5: + /// - if T is a non-union class type without a user-declared constructor, + /// then every non-static data member and base-class component of T is + /// value-initialized [...] A program that calls for [...] + /// value-initialization of an entity of reference type is ill-formed. bool hasUninitializedReferenceMember() const { return !isUnion() && !hasUserDeclaredConstructor() && data().HasUninitializedReferenceMember; } - /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class - /// that is an aggregate that has no non-static non-POD data members, no - /// reference data members, no user-defined copy assignment operator and no + /// \brief Whether this class is a POD-type (C++ [class]p4) + /// + /// For purposes of this function a class is POD if it is an aggregate + /// that has no non-static non-POD data members, no reference data + /// members, no user-defined copy assignment operator and no /// user-defined destructor. /// /// Note that this is the C++ TR1 definition of POD. @@ -1053,26 +1088,33 @@ public: /// it contains only public fields, no bases, tag kind is not 'class', etc. bool isCLike() const; - /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which - /// means it has a virtual function, virtual base, data member (other than - /// 0-width bit-field) or inherits from a non-empty class. Does NOT include - /// a check for union-ness. + /// \brief Determine whether this is an empty class in the sense of + /// (C++11 [meta.unary.prop]). + /// + /// A non-union class is empty iff it has a virtual function, virtual base, + /// data member (other than 0-width bit-field) or inherits from a non-empty + /// class. + /// + /// \note This does NOT include a check for union-ness. bool isEmpty() const { return data().Empty; } - /// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]), + /// Whether this class is polymorphic (C++ [class.virtual]), /// which means that the class contains or inherits a virtual function. bool isPolymorphic() const { return data().Polymorphic; } - /// isAbstract - Whether this class is abstract (C++ [class.abstract]), - /// which means that the class contains or inherits a pure virtual function. + /// \brief Determine whether this class has a pure virtual function. + /// + /// The class is is abstract per (C++ [class.abstract]p2) if it declares + /// a pure virtual function or inherits a pure virtual function that is + /// not overridden. bool isAbstract() const { return data().Abstract; } - /// isStandardLayout - Whether this class has standard layout + /// \brief Determine whether this class has standard layout per /// (C++ [class]p7) bool isStandardLayout() const { return data().IsStandardLayout; } - /// \brief Whether this class, or any of its class subobjects, contains a - /// mutable field. + /// \brief Determine whether this class, or any of its class subobjects, + /// contains a mutable field. bool hasMutableFields() const { return data().HasMutableFields; } /// \brief Determine whether this class has a trivial default constructor @@ -1180,47 +1222,49 @@ public: return !(data().HasTrivialSpecialMembers & SMF_Destructor); } - // hasIrrelevantDestructor - Whether this class has a destructor which has no - // semantic effect. Any such destructor will be trivial, public, defaulted - // and not deleted, and will call only irrelevant destructors. + /// \brief Determine whether this class has a destructor which has no + /// semantic effect. + /// + /// Any such destructor will be trivial, public, defaulted and not deleted, + /// and will call only irrelevant destructors. bool hasIrrelevantDestructor() const { return data().HasIrrelevantDestructor; } - // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal or - // volatile type non-static data member or base class. + /// \brief Determine whether this class has a non-literal or/ volatile type + /// non-static data member or base class. bool hasNonLiteralTypeFieldsOrBases() const { return data().HasNonLiteralTypeFieldsOrBases; } - // isTriviallyCopyable - Whether this class is considered trivially copyable - // (C++0x [class]p6). + /// \brief Determine whether this class is considered trivially copyable per + /// (C++11 [class]p6). bool isTriviallyCopyable() const; - // isTrivial - Whether this class is considered trivial - // - // C++0x [class]p6 - // A trivial class is a class that has a trivial default constructor and - // is trivially copiable. + /// \brief Determine whether this class is considered trivial. + /// + /// C++11 [class]p6: + /// "A trivial class is a class that has a trivial default constructor and + /// is trivially copiable." bool isTrivial() const { return isTriviallyCopyable() && hasTrivialDefaultConstructor(); } - // isLiteral - Whether this class is a literal type. - // - // C++11 [basic.types]p10 - // A class type that has all the following properties: - // -- it has a trivial destructor - // -- every constructor call and full-expression in the - // brace-or-equal-intializers for non-static data members (if any) is - // a constant expression. - // -- it is an aggregate type or has at least one constexpr constructor or - // constructor template that is not a copy or move constructor, and - // -- all of its non-static data members and base classes are of literal - // types - // - // We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by - // treating types with trivial default constructors as literal types. + /// \brief Determine whether this class is a literal type. + /// + /// C++11 [basic.types]p10: + /// A class type that has all the following properties: + /// - it has a trivial destructor + /// - every constructor call and full-expression in the + /// brace-or-equal-intializers for non-static data members (if any) is + /// a constant expression. + /// - it is an aggregate type or has at least one constexpr constructor + /// or constructor template that is not a copy or move constructor, and + /// - all of its non-static data members and base classes are of literal + /// types + /// + /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by + /// treating types with trivial default constructors as literal types. bool isLiteral() const { return hasTrivialDestructor() && (isAggregate() || hasConstexprNonCopyMoveConstructor() || @@ -1231,15 +1275,15 @@ public: /// \brief If this record is an instantiation of a member class, /// retrieves the member class from which it was instantiated. /// - /// This routine will return non-NULL for (non-templated) member + /// This routine will return non-null for (non-templated) member /// classes of class templates. For example, given: /// - /// @code + /// \code /// template<typename T> /// struct X { /// struct A { }; /// }; - /// @endcode + /// \endcode /// /// The declaration for X<int>::A is a (non-templated) CXXRecordDecl /// whose parent is the class template specialization X<int>. For @@ -1257,7 +1301,7 @@ public: } /// \brief Specify that this record is an instantiation of the - /// member class RD. + /// member class \p RD. void setInstantiationOfMemberClass(CXXRecordDecl *RD, TemplateSpecializationKind TSK); @@ -1288,10 +1332,10 @@ public: /// \brief Set the kind of specialization or template instantiation this is. void setTemplateSpecializationKind(TemplateSpecializationKind TSK); - /// getDestructor - Returns the destructor decl for this class. + /// \brief Returns the destructor decl for this class. CXXDestructorDecl *getDestructor() const; - /// isLocalClass - If the class is a local class [class.local], returns + /// \brief If the class is a local class [class.local], returns /// the enclosing function declaration. const FunctionDecl *isLocalClass() const { if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext())) @@ -1300,6 +1344,11 @@ public: return dyn_cast<FunctionDecl>(getDeclContext()); } + FunctionDecl *isLocalClass() { + return const_cast<FunctionDecl*>( + const_cast<const CXXRecordDecl*>(this)->isLocalClass()); + } + /// \brief Determine whether this dependent class is a current instantiation, /// when viewed from within the given context. bool isCurrentInstantiation(const DeclContext *CurContext) const; @@ -1328,7 +1377,7 @@ public: /// \param Paths will contain the paths taken from the current class to the /// given \p Base class. /// - /// \returns true if this class is derived from Base, false otherwise. + /// \returns true if this class is derived from \p Base, false otherwise. /// /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than /// tangling input and output in \p Paths @@ -1367,6 +1416,13 @@ public: /// The class itself does not count as a base class. This routine /// returns false if the class has non-computable base classes. /// + /// \param BaseMatches Callback invoked for each (direct or indirect) base + /// class of this type, or if \p AllowShortCircuit is true then until a call + /// returns false. + /// + /// \param UserData Passed as the second argument of every call to + /// \p BaseMatches. + /// /// \param AllowShortCircuit if false, forces the callback to be called /// for every base class, even if a dependent or non-matching base was /// found. @@ -1471,12 +1527,12 @@ public: /// \brief Get the indirect primary bases for this class. void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const; - /// viewInheritance - Renders and displays an inheritance diagram + /// Renders and displays an inheritance diagram /// for this C++ class and all of its base classes (transitively) using /// GraphViz. void viewInheritance(ASTContext& Context) const; - /// MergeAccess - Calculates the access of a decl that is reached + /// \brief Calculates the access of a decl that is reached /// along a path. static AccessSpecifier MergeAccess(AccessSpecifier PathAccess, AccessSpecifier DeclAccess) { @@ -1575,8 +1631,10 @@ public: friend class ASTWriter; }; -/// CXXMethodDecl - Represents a static or instance method of a -/// struct/union/class. +/// \brief Represents a static or instance method of a struct/union/class. +/// +/// In the terminology of the C++ Standard, these are the (static and +/// non-static) member functions, whether virtual or not. class CXXMethodDecl : public FunctionDecl { virtual void anchor(); protected: @@ -1606,6 +1664,18 @@ public: bool isStatic() const; bool isInstance() const { return !isStatic(); } + /// Returns true if the given operator is implicitly static in a record + /// context. + static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK) { + // [class.free]p1: + // Any allocation function for a class T is a static member + // (even if not explicitly declared static). + // [class.free]p6 Any deallocation function for a class X is a static member + // (even if not explicitly declared static). + return OOK == OO_New || OOK == OO_Array_New || OOK == OO_Delete || + OOK == OO_Array_Delete; + } + bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); } bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); } @@ -1633,14 +1703,22 @@ public: /// \brief Determine whether this is a move assignment operator. bool isMoveAssignmentOperator() const; - const CXXMethodDecl *getCanonicalDecl() const { - return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl()); - } CXXMethodDecl *getCanonicalDecl() { return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl()); } + const CXXMethodDecl *getCanonicalDecl() const { + return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl(); + } + + CXXMethodDecl *getMostRecentDecl() { + return cast<CXXMethodDecl>( + static_cast<FunctionDecl *>(this)->getMostRecentDecl()); + } + const CXXMethodDecl *getMostRecentDecl() const { + return const_cast<CXXMethodDecl*>(this)->getMostRecentDecl(); + } - /// isUserProvided - True if this method is user-declared and was not + /// True if this method is user-declared and was not /// deleted or defaulted on its first declaration. bool isUserProvided() const { return !(isDeleted() || getCanonicalDecl()->isDefaulted()); @@ -1655,21 +1733,22 @@ public: method_iterator end_overridden_methods() const; unsigned size_overridden_methods() const; - /// getParent - Returns the parent of this method declaration, which + /// Returns the parent of this method declaration, which /// is the class in which this method is defined. const CXXRecordDecl *getParent() const { return cast<CXXRecordDecl>(FunctionDecl::getParent()); } - /// getParent - Returns the parent of this method declaration, which + /// Returns the parent of this method declaration, which /// is the class in which this method is defined. CXXRecordDecl *getParent() { return const_cast<CXXRecordDecl *>( cast<CXXRecordDecl>(FunctionDecl::getParent())); } - /// getThisType - Returns the type of 'this' pointer. - /// Should only be called for instance methods. + /// \brief Returns the type of the \c this pointer. + /// + /// Should only be called for instance (i.e., non-static) methods. QualType getThisType(ASTContext &C) const; unsigned getTypeQualifiers() const { @@ -1702,11 +1781,11 @@ public: /// or clone the function call operator. bool isLambdaStaticInvoker() const; - /// \brief Find the method in RD that corresponds to this one. + /// \brief Find the method in \p RD that corresponds to this one. /// - /// Find if RD or one of the classes it inherits from override this method. - /// If so, return it. RD is assumed to be a subclass of the class defining - /// this method (or be the class itself), unless MayBeBase is set to true. + /// Find if \p RD or one of the classes it inherits from override this method. + /// If so, return it. \p RD is assumed to be a subclass of the class defining + /// this method (or be the class itself), unless \p MayBeBase is set to true. CXXMethodDecl * getCorrespondingMethodInClass(const CXXRecordDecl *RD, bool MayBeBase = false); @@ -1725,20 +1804,21 @@ public: } }; -/// CXXCtorInitializer - Represents a C++ base or member -/// initializer, which is part of a constructor initializer that +/// \brief Represents a C++ base or member initializer. +/// +/// This is part of a constructor initializer that /// initializes one non-static member variable or one base class. For /// example, in the following, both 'A(a)' and 'f(3.14159)' are member /// initializers: /// -/// @code +/// \code /// class A { }; /// class B : public A { /// float f; /// public: /// B(A& a) : A(a), f(3.14159) { } /// }; -/// @endcode +/// \endcode class CXXCtorInitializer { /// \brief Either the base class name/delegating constructor type (stored as /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field @@ -1747,7 +1827,9 @@ class CXXCtorInitializer { Initializee; /// \brief The source location for the field name or, for a base initializer - /// pack expansion, the location of the ellipsis. In the case of a delegating + /// pack expansion, the location of the ellipsis. + /// + /// In the case of a delegating /// constructor, it will still include the type's source location as the /// Initializee points to the CXXConstructorDecl (to allow loop detection). SourceLocation MemberOrEllipsisLocation; @@ -1756,29 +1838,28 @@ class CXXCtorInitializer { /// end up constructing an object (when multiple arguments are involved). Stmt *Init; - /// LParenLoc - Location of the left paren of the ctor-initializer. + /// \brief Location of the left paren of the ctor-initializer. SourceLocation LParenLoc; - /// RParenLoc - Location of the right paren of the ctor-initializer. + /// \brief Location of the right paren of the ctor-initializer. SourceLocation RParenLoc; /// \brief If the initializee is a type, whether that type makes this /// a delegating initialization. bool IsDelegating : 1; - /// IsVirtual - If the initializer is a base initializer, this keeps track + /// \brief If the initializer is a base initializer, this keeps track /// of whether the base is virtual or not. bool IsVirtual : 1; - /// IsWritten - Whether or not the initializer is explicitly written + /// \brief Whether or not the initializer is explicitly written /// in the sources. bool IsWritten : 1; - /// SourceOrderOrNumArrayIndices - If IsWritten is true, then this - /// number keeps track of the textual order of this initializer in the - /// original sources, counting from 0; otherwise, if IsWritten is false, - /// it stores the number of array index variables stored after this - /// object in memory. + /// If IsWritten is true, then this number keeps track of the textual order + /// of this initializer in the original sources, counting from 0; otherwise, + /// it stores the number of array index variables stored after this object + /// in memory. unsigned SourceOrderOrNumArrayIndices : 13; CXXCtorInitializer(ASTContext &Context, FieldDecl *Member, @@ -1786,25 +1867,25 @@ class CXXCtorInitializer { SourceLocation R, VarDecl **Indices, unsigned NumIndices); public: - /// CXXCtorInitializer - Creates a new base-class initializer. + /// \brief Creates a new base-class initializer. explicit CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual, SourceLocation L, Expr *Init, SourceLocation R, SourceLocation EllipsisLoc); - /// CXXCtorInitializer - Creates a new member initializer. + /// \brief Creates a new member initializer. explicit CXXCtorInitializer(ASTContext &Context, FieldDecl *Member, SourceLocation MemberLoc, SourceLocation L, Expr *Init, SourceLocation R); - /// CXXCtorInitializer - Creates a new anonymous field initializer. + /// \brief Creates a new anonymous field initializer. explicit CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member, SourceLocation MemberLoc, SourceLocation L, Expr *Init, SourceLocation R); - /// CXXCtorInitializer - Creates a new delegating Initializer. + /// \brief Creates a new delegating initializer. explicit CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, SourceLocation L, Expr *Init, SourceLocation R); @@ -1816,14 +1897,13 @@ public: Expr *Init, SourceLocation R, VarDecl **Indices, unsigned NumIndices); - /// isBaseInitializer - Returns true when this initializer is - /// initializing a base class. + /// \brief Determine whether this initializer is initializing a base class. bool isBaseInitializer() const { return Initializee.is<TypeSourceInfo*>() && !IsDelegating; } - /// isMemberInitializer - Returns true when this initializer is - /// initializing a non-static data member. + /// \brief Determine whether this initializer is initializing a non-static + /// data member. bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); } bool isAnyMemberInitializer() const { @@ -1834,15 +1914,18 @@ public: return Initializee.is<IndirectFieldDecl*>(); } - /// isInClassMemberInitializer - Returns true when this initializer is an - /// implicit ctor initializer generated for a field with an initializer - /// defined on the member declaration. + /// \brief Determine whether this initializer is an implicit initializer + /// generated for a field with an initializer defined on the member + /// declaration. + /// + /// In-class member initializers (also known as "non-static data member + /// initializations", NSDMIs) were introduced in C++11. bool isInClassMemberInitializer() const { return isa<CXXDefaultInitExpr>(Init); } - /// isDelegatingInitializer - Returns true when this initializer is creating - /// a delegating constructor. + /// \brief Determine whether this initializer is creating a delegating + /// constructor. bool isDelegatingInitializer() const { return Initializee.is<TypeSourceInfo*>() && IsDelegating; } @@ -1864,7 +1947,7 @@ public: TypeLoc getBaseClassLoc() const; /// If this is a base class initializer, returns the type of the base class. - /// Otherwise, returns NULL. + /// Otherwise, returns null. const Type *getBaseClass() const; /// Returns whether the base is virtual or not. @@ -1880,9 +1963,8 @@ public: return Initializee.dyn_cast<TypeSourceInfo *>(); } - /// getMember - If this is a member initializer, returns the - /// declaration of the non-static data member being - /// initialized. Otherwise, returns NULL. + /// \brief If this is a member initializer, returns the declaration of the + /// non-static data member being initialized. Otherwise, returns null. FieldDecl *getMember() const { if (isMemberInitializer()) return Initializee.get<FieldDecl*>(); @@ -1912,7 +1994,7 @@ public: /// \brief Determine the source range covering the entire initializer. SourceRange getSourceRange() const LLVM_READONLY; - /// isWritten - Returns true if this initializer is explicitly written + /// \brief Determine whether this initializer is explicitly written /// in the source code. bool isWritten() const { return IsWritten; } @@ -1922,9 +2004,13 @@ public: return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1; } - /// \brief Set the source order of this initializer. This method can only - /// be called once for each initializer; it cannot be called on an - /// initializer having a positive number of (implicit) array indices. + /// \brief Set the source order of this initializer. + /// + /// This can only be called once for each initializer; it cannot be called + /// on an initializer having a positive number of (implicit) array indices. + /// + /// This assumes that the initialzier was written in the source code, and + /// ensures that isWritten() returns true. void setSourceOrder(int pos) { assert(!IsWritten && "calling twice setSourceOrder() on the same initializer"); @@ -1969,34 +2055,28 @@ public: Expr *getInit() const { return static_cast<Expr*>(Init); } }; -/// CXXConstructorDecl - Represents a C++ constructor within a -/// class. For example: +/// \brief Represents a C++ constructor within a class. /// -/// @code +/// For example: +/// +/// \code /// class X { /// public: /// explicit X(int); // represented by a CXXConstructorDecl. /// }; -/// @endcode +/// \endcode class CXXConstructorDecl : public CXXMethodDecl { virtual void anchor(); - /// IsExplicitSpecified - Whether this constructor declaration has the - /// 'explicit' keyword specified. + /// \brief Whether this constructor declaration has the \c explicit keyword + /// specified. bool IsExplicitSpecified : 1; - /// ImplicitlyDefined - Whether this constructor was implicitly - /// defined by the compiler. When false, the constructor was defined - /// by the user. In C++03, this flag will have the same value as - /// Implicit. In C++0x, however, a constructor that is - /// explicitly defaulted (i.e., defined with " = default") will have - /// @c !Implicit && ImplicitlyDefined. - bool ImplicitlyDefined : 1; - - /// Support for base and member initializers. - /// CtorInitializers - The arguments used to initialize the base - /// or member. + /// \name Support for base and member initializers. + /// \{ + /// \brief The arguments used to initialize the base or member. CXXCtorInitializer **CtorInitializers; unsigned NumCtorInitializers; + /// \} CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, @@ -2005,8 +2085,8 @@ class CXXConstructorDecl : public CXXMethodDecl { bool isImplicitlyDeclared, bool isConstexpr) : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, SourceLocation()), - IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false), - CtorInitializers(0), NumCtorInitializers(0) { + IsExplicitSpecified(isExplicitSpecified), CtorInitializers(0), + NumCtorInitializers(0) { setImplicit(isImplicitlyDeclared); } @@ -2020,52 +2100,31 @@ public: bool isInline, bool isImplicitlyDeclared, bool isConstexpr); - /// isExplicitSpecified - Whether this constructor declaration has the - /// 'explicit' keyword specified. + /// \brief Determine whether this constructor declaration has the + /// \c explicit keyword specified. bool isExplicitSpecified() const { return IsExplicitSpecified; } - /// isExplicit - Whether this constructor was marked "explicit" or not. + /// \brief Determine whether this constructor was marked "explicit" or not. bool isExplicit() const { - return cast<CXXConstructorDecl>(getFirstDeclaration()) - ->isExplicitSpecified(); - } - - /// isImplicitlyDefined - Whether this constructor was implicitly - /// defined. If false, then this constructor was defined by the - /// user. This operation can only be invoked if the constructor has - /// already been defined. - bool isImplicitlyDefined() const { - assert(isThisDeclarationADefinition() && - "Can only get the implicit-definition flag once the " - "constructor has been defined"); - return ImplicitlyDefined; - } - - /// setImplicitlyDefined - Set whether this constructor was - /// implicitly defined or not. - void setImplicitlyDefined(bool ID) { - assert(isThisDeclarationADefinition() && - "Can only set the implicit-definition flag once the constructor " - "has been defined"); - ImplicitlyDefined = ID; + return cast<CXXConstructorDecl>(getFirstDecl())->isExplicitSpecified(); } - /// init_iterator - Iterates through the member/base initializer list. + /// \brief Iterates through the member/base initializer list. typedef CXXCtorInitializer **init_iterator; - /// init_const_iterator - Iterates through the memberbase initializer list. + /// \brief Iterates through the member/base initializer list. typedef CXXCtorInitializer * const * init_const_iterator; - /// init_begin() - Retrieve an iterator to the first initializer. + /// \brief Retrieve an iterator to the first initializer. init_iterator init_begin() { return CtorInitializers; } - /// begin() - Retrieve an iterator to the first initializer. + /// \brief Retrieve an iterator to the first initializer. init_const_iterator init_begin() const { return CtorInitializers; } - /// init_end() - Retrieve an iterator past the last initializer. + /// \brief Retrieve an iterator past the last initializer. init_iterator init_end() { return CtorInitializers + NumCtorInitializers; } - /// end() - Retrieve an iterator past the last initializer. + /// \brief Retrieve an iterator past the last initializer. init_const_iterator init_end() const { return CtorInitializers + NumCtorInitializers; } @@ -2088,8 +2147,8 @@ public: return init_const_reverse_iterator(init_begin()); } - /// getNumArgs - Determine the number of arguments used to - /// initialize the member or base. + /// \brief Determine the number of arguments used to initialize the member + /// or base. unsigned getNumCtorInitializers() const { return NumCtorInitializers; } @@ -2102,37 +2161,36 @@ public: CtorInitializers = initializers; } - /// isDelegatingConstructor - Whether this constructor is a - /// delegating constructor + /// \brief Determine whether this constructor is a delegating constructor. bool isDelegatingConstructor() const { return (getNumCtorInitializers() == 1) && CtorInitializers[0]->isDelegatingInitializer(); } - /// getTargetConstructor - When this constructor delegates to - /// another, retrieve the target + /// \brief When this constructor delegates to another, retrieve the target. CXXConstructorDecl *getTargetConstructor() const; - /// isDefaultConstructor - Whether this constructor is a default + /// Whether this constructor is a default /// constructor (C++ [class.ctor]p5), which can be used to /// default-initialize a class of this type. bool isDefaultConstructor() const; - /// isCopyConstructor - Whether this constructor is a copy - /// constructor (C++ [class.copy]p2, which can be used to copy the - /// class. @p TypeQuals will be set to the qualifiers on the - /// argument type. For example, @p TypeQuals would be set to @c + /// \brief Whether this constructor is a copy constructor (C++ [class.copy]p2, + /// which can be used to copy the class. + /// + /// \p TypeQuals will be set to the qualifiers on the + /// argument type. For example, \p TypeQuals would be set to \c /// Qualifiers::Const for the following copy constructor: /// - /// @code + /// \code /// class X { /// public: /// X(const X&); /// }; - /// @endcode + /// \endcode bool isCopyConstructor(unsigned &TypeQuals) const; - /// isCopyConstructor - Whether this constructor is a copy + /// Whether this constructor is a copy /// constructor (C++ [class.copy]p2, which can be used to copy the /// class. bool isCopyConstructor() const { @@ -2166,7 +2224,7 @@ public: return isCopyOrMoveConstructor(Quals); } - /// isConvertingConstructor - Whether this constructor is a + /// Whether this constructor is a /// converting constructor (C++ [class.conv.ctor]), which can be /// used for user-defined conversions. bool isConvertingConstructor(bool AllowExplicit) const; @@ -2197,24 +2255,18 @@ public: friend class ASTDeclWriter; }; -/// CXXDestructorDecl - Represents a C++ destructor within a -/// class. For example: +/// \brief Represents a C++ destructor within a class. /// -/// @code +/// For example: +/// +/// \code /// class X { /// public: /// ~X(); // represented by a CXXDestructorDecl. /// }; -/// @endcode +/// \endcode class CXXDestructorDecl : public CXXMethodDecl { virtual void anchor(); - /// ImplicitlyDefined - Whether this destructor was implicitly - /// defined by the compiler. When false, the destructor was defined - /// by the user. In C++03, this flag will have the same value as - /// Implicit. In C++0x, however, a destructor that is - /// explicitly defaulted (i.e., defined with " = default") will have - /// @c !Implicit && ImplicitlyDefined. - bool ImplicitlyDefined : 1; FunctionDecl *OperatorDelete; @@ -2224,7 +2276,7 @@ class CXXDestructorDecl : public CXXMethodDecl { bool isInline, bool isImplicitlyDeclared) : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, /*isConstexpr=*/false, SourceLocation()), - ImplicitlyDefined(false), OperatorDelete(0) { + OperatorDelete(0) { setImplicit(isImplicitlyDeclared); } @@ -2237,26 +2289,6 @@ public: bool isImplicitlyDeclared); static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); - /// isImplicitlyDefined - Whether this destructor was implicitly - /// defined. If false, then this destructor was defined by the - /// user. This operation can only be invoked if the destructor has - /// already been defined. - bool isImplicitlyDefined() const { - assert(isThisDeclarationADefinition() && - "Can only get the implicit-definition flag once the destructor has " - "been defined"); - return ImplicitlyDefined; - } - - /// setImplicitlyDefined - Set whether this destructor was - /// implicitly defined or not. - void setImplicitlyDefined(bool ID) { - assert(isThisDeclarationADefinition() && - "Can only set the implicit-definition flag once the destructor has " - "been defined"); - ImplicitlyDefined = ID; - } - void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; } const FunctionDecl *getOperatorDelete() const { return OperatorDelete; } @@ -2268,19 +2300,20 @@ public: friend class ASTDeclWriter; }; -/// CXXConversionDecl - Represents a C++ conversion function within a -/// class. For example: +/// \brief Represents a C++ conversion function within a class. +/// +/// For example: /// -/// @code +/// \code /// class X { /// public: /// operator bool(); /// }; -/// @endcode +/// \endcode class CXXConversionDecl : public CXXMethodDecl { virtual void anchor(); - /// IsExplicitSpecified - Whether this conversion function declaration is - /// marked "explicit", meaning that it can only be applied when the user + /// Whether this conversion function declaration is marked + /// "explicit", meaning that it can only be applied when the user /// explicitly wrote a cast. This is a C++0x feature. bool IsExplicitSpecified : 1; @@ -2303,21 +2336,20 @@ public: SourceLocation EndLocation); static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); - /// IsExplicitSpecified - Whether this conversion function declaration is - /// marked "explicit", meaning that it can only be applied when the user - /// explicitly wrote a cast. This is a C++0x feature. + /// Whether this conversion function declaration is marked + /// "explicit", meaning that it can only be used for direct initialization + /// (including explitly written casts). This is a C++11 feature. bool isExplicitSpecified() const { return IsExplicitSpecified; } - /// isExplicit - Whether this is an explicit conversion operator - /// (C++0x only). Explicit conversion operators are only considered - /// when the user has explicitly written a cast. + /// \brief Whether this is an explicit conversion operator (C++11 and later). + /// + /// Explicit conversion operators are only considered for direct + /// initialization, e.g., when the user has explicitly written a cast. bool isExplicit() const { - return cast<CXXConversionDecl>(getFirstDeclaration()) - ->isExplicitSpecified(); + return cast<CXXConversionDecl>(getFirstDecl())->isExplicitSpecified(); } - /// getConversionType - Returns the type that this conversion - /// function is converting to. + /// \brief Returns the type that this conversion function is converting to. QualType getConversionType() const { return getType()->getAs<FunctionType>()->getResultType(); } @@ -2334,32 +2366,37 @@ public: friend class ASTDeclWriter; }; -/// LinkageSpecDecl - This represents a linkage specification. For example: -/// extern "C" void foo(); +/// \brief Represents a linkage specification. /// +/// For example: +/// \code +/// extern "C" void foo(); +/// \endcode class LinkageSpecDecl : public Decl, public DeclContext { virtual void anchor(); public: - /// LanguageIDs - Used to represent the language in a linkage - /// specification. The values are part of the serialization abi for - /// ASTs and cannot be changed without altering that abi. To help - /// ensure a stable abi for this, we choose the DW_LANG_ encodings + /// \brief Represents the language in a linkage specification. + /// + /// The values are part of the serialization ABI for + /// ASTs and cannot be changed without altering that ABI. To help + /// ensure a stable ABI for this, we choose the DW_LANG_ encodings /// from the dwarf standard. enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002, lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 }; private: - /// Language - The language for this linkage specification. + /// \brief The language for this linkage specification. unsigned Language : 3; - /// True if this linkage spec has brances. This is needed so that hasBraces() - /// returns the correct result while the linkage spec body is being parsed. - /// Once RBraceLoc has been set this is not used, so it doesn't need to be - /// serialized. + /// \brief True if this linkage spec has braces. + /// + /// This is needed so that hasBraces() returns the correct result while the + /// linkage spec body is being parsed. Once RBraceLoc has been set this is + /// not used, so it doesn't need to be serialized. unsigned HasBraces : 1; - /// ExternLoc - The source location for the extern keyword. + /// \brief The source location for the extern keyword. SourceLocation ExternLoc; - /// RBraceLoc - The source location for the right brace (if valid). + /// \brief The source location for the right brace (if valid). SourceLocation RBraceLoc; LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc, @@ -2417,34 +2454,38 @@ public: } }; -/// UsingDirectiveDecl - Represents C++ using-directive. For example: +/// \brief Represents C++ using-directive. /// +/// For example: +/// \code /// using namespace std; +/// \endcode /// -// NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide -// artificial names for all using-directives in order to store -// them in DeclContext effectively. +/// \note UsingDirectiveDecl should be Decl not NamedDecl, but we provide +/// artificial names for all using-directives in order to store +/// them in DeclContext effectively. class UsingDirectiveDecl : public NamedDecl { virtual void anchor(); - /// \brief The location of the "using" keyword. + /// \brief The location of the \c using keyword. SourceLocation UsingLoc; - /// SourceLocation - Location of 'namespace' token. + /// \brief The location of the \c namespace keyword. SourceLocation NamespaceLoc; /// \brief The nested-name-specifier that precedes the namespace. NestedNameSpecifierLoc QualifierLoc; - /// NominatedNamespace - Namespace nominated by using-directive. + /// \brief The namespace nominated by this using-directive. NamedDecl *NominatedNamespace; /// Enclosing context containing both using-directive and nominated /// namespace. DeclContext *CommonAncestor; - /// getUsingDirectiveName - Returns special DeclarationName used by - /// using-directives. This is only used by DeclContext for storing - /// UsingDirectiveDecls in its lookup structure. + /// \brief Returns special DeclarationName used by using-directives. + /// + /// This is only used by DeclContext for storing UsingDirectiveDecls in + /// its lookup structure. static DeclarationName getName() { return DeclarationName::getUsingDirectiveName(); } @@ -2475,7 +2516,7 @@ public: return NominatedNamespace; } - /// getNominatedNamespace - Returns namespace nominated by using-directive. + /// \brief Returns the namespace nominated by this using-directive. NamespaceDecl *getNominatedNamespace(); const NamespaceDecl *getNominatedNamespace() const { @@ -2487,14 +2528,14 @@ public: DeclContext *getCommonAncestor() { return CommonAncestor; } const DeclContext *getCommonAncestor() const { return CommonAncestor; } - /// \brief Return the location of the "using" keyword. + /// \brief Return the location of the \c using keyword. SourceLocation getUsingLoc() const { return UsingLoc; } // FIXME: Could omit 'Key' in name. - /// getNamespaceKeyLocation - Returns location of namespace keyword. + /// \brief Returns the location of the \c namespace keyword. SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; } - /// getIdentLocation - Returns location of identifier. + /// \brief Returns the location of this using declaration's identifier. SourceLocation getIdentLocation() const { return getLocation(); } static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC, @@ -2523,23 +2564,25 @@ public: /// /// For example: /// -/// @code +/// \code /// namespace Foo = Bar; -/// @endcode +/// \endcode class NamespaceAliasDecl : public NamedDecl { virtual void anchor(); - /// \brief The location of the "namespace" keyword. + /// \brief The location of the \c namespace keyword. SourceLocation NamespaceLoc; - /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc. + /// \brief The location of the namespace's identifier. + /// + /// This is accessed by TargetNameLoc. SourceLocation IdentLoc; /// \brief The nested-name-specifier that precedes the namespace. NestedNameSpecifierLoc QualifierLoc; - /// Namespace - The Decl that this alias points to. Can either be a - /// NamespaceDecl or a NamespaceAliasDecl. + /// \brief The Decl that this alias points to, either a NamespaceDecl or + /// a NamespaceAliasDecl. NamedDecl *Namespace; NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc, @@ -2579,7 +2622,7 @@ public: /// "namespace foo = ns::bar;". SourceLocation getAliasLoc() const { return getLocation(); } - /// Returns the location of the 'namespace' keyword. + /// Returns the location of the \c namespace keyword. SourceLocation getNamespaceLoc() const { return NamespaceLoc; } /// Returns the location of the identifier in the named namespace. @@ -2611,7 +2654,7 @@ public: /// (resolved) using declaration. /// /// For example, -/// @code +/// \code /// namespace A { /// void foo(); /// } @@ -2619,8 +2662,8 @@ public: /// using A::foo; // <- a UsingDecl /// // Also creates a UsingShadowDecl for A::foo() in B /// } -/// @endcode -class UsingShadowDecl : public NamedDecl { +/// \endcode +class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> { virtual void anchor(); /// The referenced declaration. @@ -2643,6 +2686,17 @@ class UsingShadowDecl : public NamedDecl { setImplicit(); } + typedef Redeclarable<UsingShadowDecl> redeclarable_base; + virtual UsingShadowDecl *getNextRedeclaration() { + return RedeclLink.getNext(); + } + virtual UsingShadowDecl *getPreviousDeclImpl() { + return getPreviousDecl(); + } + virtual UsingShadowDecl *getMostRecentDeclImpl() { + return getMostRecentDecl(); + } + public: static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, UsingDecl *Using, @@ -2651,7 +2705,20 @@ public: } static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + + typedef redeclarable_base::redecl_iterator redecl_iterator; + using redeclarable_base::redecls_begin; + using redeclarable_base::redecls_end; + using redeclarable_base::getPreviousDecl; + using redeclarable_base::getMostRecentDecl; + + virtual UsingShadowDecl *getCanonicalDecl() { + return getFirstDecl(); + } + virtual const UsingShadowDecl *getCanonicalDecl() const { + return getFirstDecl(); + } + /// \brief Gets the underlying declaration which has been brought into the /// local scope. NamedDecl *getTargetDecl() const { return Underlying; } @@ -2683,20 +2750,20 @@ public: /// \brief Represents a C++ using-declaration. /// /// For example: -/// @code +/// \code /// using someNameSpace::someIdentifier; -/// @endcode +/// \endcode class UsingDecl : public NamedDecl { virtual void anchor(); - /// \brief The source location of the "using" location itself. + /// \brief The source location of the 'using' keyword itself. SourceLocation UsingLocation; /// \brief The nested-name-specifier that precedes the name. NestedNameSpecifierLoc QualifierLoc; - /// DNLoc - Provides source/type location info for the - /// declaration name embedded in the ValueDecl base class. + /// \brief Provides source/type location info for the declaration name + /// embedded in the ValueDecl base class. DeclarationNameLoc DNLoc; /// \brief The first shadow declaration of the shadow decl chain associated @@ -2708,18 +2775,18 @@ class UsingDecl : public NamedDecl { UsingDecl(DeclContext *DC, SourceLocation UL, NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo, bool IsTypeNameArg) + const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword) : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()), UsingLocation(UL), QualifierLoc(QualifierLoc), - DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, IsTypeNameArg) { + DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, HasTypenameKeyword) { } public: - /// \brief Returns the source location of the "using" keyword. - SourceLocation getUsingLocation() const { return UsingLocation; } + /// \brief Return the source location of the 'using' keyword. + SourceLocation getUsingLoc() const { return UsingLocation; } /// \brief Set the source location of the 'using' keyword. - void setUsingLocation(SourceLocation L) { UsingLocation = L; } + void setUsingLoc(SourceLocation L) { UsingLocation = L; } /// \brief Retrieve the nested-name-specifier that qualifies the name, /// with source-location information. @@ -2734,13 +2801,16 @@ public: return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } + /// \brief Return true if it is a C++03 access declaration (no 'using'). + bool isAccessDeclaration() const { return UsingLocation.isInvalid(); } + /// \brief Return true if the using declaration has 'typename'. - bool isTypeName() const { return FirstUsingShadow.getInt(); } + bool hasTypename() const { return FirstUsingShadow.getInt(); } /// \brief Sets whether the using declaration has 'typename'. - void setTypeName(bool TN) { FirstUsingShadow.setInt(TN); } + void setTypename(bool TN) { FirstUsingShadow.setInt(TN); } - /// \brief Iterates through the using shadow declarations assosiated with + /// \brief Iterates through the using shadow declarations associated with /// this using declaration. class shadow_iterator { /// \brief The current using shadow declaration. @@ -2796,13 +2866,11 @@ public: SourceLocation UsingL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, - bool IsTypeNameArg); + bool HasTypenameKeyword); static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(UsingLocation, getNameInfo().getEndLoc()); - } + + SourceRange getSourceRange() const LLVM_READONLY; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Using; } @@ -2817,11 +2885,11 @@ public: /// Unlike non-dependent using declarations, these *only* bring through /// non-types; otherwise they would break two-phase lookup. /// -/// @code +/// \code /// template \<class T> class A : public Base<T> { /// using Base<T>::foo; /// }; -/// @endcode +/// \endcode class UnresolvedUsingValueDecl : public ValueDecl { virtual void anchor(); @@ -2831,8 +2899,8 @@ class UnresolvedUsingValueDecl : public ValueDecl { /// \brief The nested-name-specifier that precedes the name. NestedNameSpecifierLoc QualifierLoc; - /// DNLoc - Provides source/type location info for the - /// declaration name embedded in the ValueDecl base class. + /// \brief Provides source/type location info for the declaration name + /// embedded in the ValueDecl base class. DeclarationNameLoc DNLoc; UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty, @@ -2852,6 +2920,9 @@ public: /// \brief Set the source location of the 'using' keyword. void setUsingLoc(SourceLocation L) { UsingLocation = L; } + /// \brief Return true if it is a C++03 access declaration (no 'using'). + bool isAccessDeclaration() const { return UsingLocation.isInvalid(); } + /// \brief Retrieve the nested-name-specifier that qualifies the name, /// with source-location information. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } @@ -2873,9 +2944,7 @@ public: static UnresolvedUsingValueDecl * CreateDeserialized(ASTContext &C, unsigned ID); - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(UsingLocation, getNameInfo().getEndLoc()); - } + SourceRange getSourceRange() const LLVM_READONLY; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == UnresolvedUsingValue; } @@ -2884,23 +2953,20 @@ public: friend class ASTDeclWriter; }; -/// @brief Represents a dependent using declaration which was marked with +/// \brief Represents a dependent using declaration which was marked with /// \c typename. /// -/// @code +/// \code /// template \<class T> class A : public Base<T> { /// using typename Base<T>::foo; /// }; -/// @endcode +/// \endcode /// /// The type associated with an unresolved using typename decl is /// currently always a typename type. class UnresolvedUsingTypenameDecl : public TypeDecl { virtual void anchor(); - /// \brief The source location of the 'using' keyword - SourceLocation UsingLocation; - /// \brief The source location of the 'typename' keyword SourceLocation TypenameLocation; diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h b/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h index 84f3698..9c626c8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclContextInternals.h @@ -18,6 +18,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclarationName.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" #include <algorithm> @@ -26,23 +27,29 @@ namespace clang { class DependentDiagnostic; -/// StoredDeclsList - This is an array of decls optimized a common case of only -/// containing one entry. +/// \brief An array of decls optimized for the common case of only containing +/// one entry. struct StoredDeclsList { - /// DeclsTy - When in vector form, this is what the Data pointer points to. + /// \brief When in vector form, this is what the Data pointer points to. typedef SmallVector<NamedDecl *, 4> DeclsTy; + /// \brief A collection of declarations, with a flag to indicate if we have + /// further external declarations. + typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy; + /// \brief The stored data, which will be either a pointer to a NamedDecl, - /// or a pointer to a vector. - llvm::PointerUnion<NamedDecl *, DeclsTy *> Data; + /// or a pointer to a vector with a flag to indicate if there are further + /// external declarations. + llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data; public: StoredDeclsList() {} StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) { if (DeclsTy *RHSVec = RHS.getAsVector()) - Data = new DeclsTy(*RHSVec); + Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec), + RHS.hasExternalDecls()); } ~StoredDeclsList() { @@ -56,7 +63,7 @@ public: delete Vector; Data = RHS.Data; if (DeclsTy *RHSVec = RHS.getAsVector()) - Data = new DeclsTy(*RHSVec); + Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec), hasExternalDecls()); return *this; } @@ -66,8 +73,27 @@ public: return Data.dyn_cast<NamedDecl *>(); } + DeclsAndHasExternalTy getAsVectorAndHasExternal() const { + return Data.dyn_cast<DeclsAndHasExternalTy>(); + } + DeclsTy *getAsVector() const { - return Data.dyn_cast<DeclsTy *>(); + return getAsVectorAndHasExternal().getPointer(); + } + + bool hasExternalDecls() const { + return getAsVectorAndHasExternal().getInt(); + } + + void setHasExternalDecls() { + if (DeclsTy *Vec = getAsVector()) + Data = DeclsAndHasExternalTy(Vec, true); + else { + DeclsTy *VT = new DeclsTy(); + if (NamedDecl *OldD = getAsDecl()) + VT->push_back(OldD); + Data = DeclsAndHasExternalTy(VT, true); + } } void setOnlyValue(NamedDecl *ND) { @@ -110,6 +136,8 @@ public: Vec.erase(std::remove_if(Vec.begin(), Vec.end(), std::mem_fun(&Decl::isFromASTFile)), Vec.end()); + // Don't have any external decls any more. + Data = DeclsAndHasExternalTy(&Vec, false); } } @@ -165,12 +193,14 @@ public: /// not a redeclaration to merge it into the appropriate place in our list. /// void AddSubsequentDecl(NamedDecl *D) { + assert(!isNull() && "don't AddSubsequentDecl when we have no decls"); + // If this is the second decl added to the list, convert this to vector // form. if (NamedDecl *OldD = getAsDecl()) { DeclsTy *VT = new DeclsTy(); VT->push_back(OldD); - Data = VT; + Data = DeclsAndHasExternalTy(VT, false); } DeclsTy &Vec = *getAsVector(); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h index 3a12878..be6f2eb 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h @@ -220,7 +220,7 @@ public: }; inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const { - return friend_iterator(data().FirstFriend); + return friend_iterator(getFirstFriend()); } inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const { @@ -228,7 +228,7 @@ inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const { } inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) { - assert(FD->NextFriend == 0 && "friend already has next friend?"); + assert(!FD->NextFriend && "friend already has next friend?"); FD->NextFriend = data().FirstFriend; data().FirstFriend = FD; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h b/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h index 4477c25..c16975a 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclLookups.h @@ -37,6 +37,8 @@ public: StoredDeclsMap::iterator End) : It(It), End(End) {} + DeclarationName getLookupName() const { return It->first; } + reference operator*() const { return It->second.getLookupResult(); } pointer operator->() const { return It->second.getLookupResult(); } @@ -66,7 +68,7 @@ public: } }; -DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { +inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext(); if (Primary->hasExternalVisibleStorage()) getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary); @@ -75,7 +77,7 @@ DeclContext::all_lookups_iterator DeclContext::lookups_begin() const { return all_lookups_iterator(); } -DeclContext::all_lookups_iterator DeclContext::lookups_end() const { +inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const { DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext(); if (Primary->hasExternalVisibleStorage()) getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary); @@ -84,6 +86,22 @@ DeclContext::all_lookups_iterator DeclContext::lookups_end() const { return all_lookups_iterator(); } +inline +DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const { + DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext(); + if (StoredDeclsMap *Map = Primary->getLookupPtr()) + return all_lookups_iterator(Map->begin(), Map->end()); + return all_lookups_iterator(); +} + +inline +DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const { + DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext(); + if (StoredDeclsMap *Map = Primary->getLookupPtr()) + return all_lookups_iterator(Map->end(), Map->end()); + return all_lookups_iterator(); +} + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h index 40de013..2e760d6 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h @@ -452,7 +452,7 @@ public: } /// \brief Determine whether this method has a body. - virtual bool hasBody() const { return Body; } + virtual bool hasBody() const { return Body.isValid(); } /// \brief Retrieve the body of this method, if it has one. virtual Stmt *getBody() const; @@ -463,7 +463,7 @@ public: void setBody(Stmt *B) { Body = B; } /// \brief Returns whether this specific method is a definition. - bool isThisDeclarationADefinition() const { return Body; } + bool isThisDeclarationADefinition() const { return hasBody(); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -553,6 +553,9 @@ public: typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap; + typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*> + ProtocolPropertyMap; + typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder; /// This routine collects list of properties to be implemented in the class. @@ -1133,6 +1136,8 @@ public: return lookupInstanceVariable(IVarName, ClassDeclared); } + ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name); + // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, @@ -1196,14 +1201,11 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; /// Retrieves the canonical declaration of this Objective-C class. - ObjCInterfaceDecl *getCanonicalDecl() { - return getFirstDeclaration(); - } - const ObjCInterfaceDecl *getCanonicalDecl() const { - return getFirstDeclaration(); - } + ObjCInterfaceDecl *getCanonicalDecl() { return getFirstDecl(); } + const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); } // Low-level accessor const Type *getTypeForDecl() const { return TypeForDecl; } @@ -1244,10 +1246,12 @@ private: ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, - bool synthesized) + bool synthesized, + bool backingIvarReferencedInAccessor) : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit), - NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {} + NextIvar(0), DeclAccess(ac), Synthesized(synthesized), + BackingIvarReferencedInAccessor(backingIvarReferencedInAccessor) {} public: static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC, @@ -1255,7 +1259,8 @@ public: IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW = NULL, - bool synthesized=false); + bool synthesized=false, + bool backingIvarReferencedInAccessor=false); static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1277,6 +1282,13 @@ public: return DeclAccess == None ? Protected : AccessControl(DeclAccess); } + void setBackingIvarReferencedInAccessor(bool val) { + BackingIvarReferencedInAccessor = val; + } + bool getBackingIvarReferencedInAccessor() const { + return BackingIvarReferencedInAccessor; + } + void setSynthesize(bool synth) { Synthesized = synth; } bool getSynthesize() const { return Synthesized; } @@ -1291,6 +1303,7 @@ private: // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum unsigned DeclAccess : 3; unsigned Synthesized : 1; + unsigned BackingIvarReferencedInAccessor : 1; }; @@ -1502,17 +1515,17 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; /// Retrieves the canonical declaration of this Objective-C protocol. - ObjCProtocolDecl *getCanonicalDecl() { - return getFirstDeclaration(); - } - const ObjCProtocolDecl *getCanonicalDecl() const { - return getFirstDeclaration(); - } + ObjCProtocolDecl *getCanonicalDecl() { return getFirstDecl(); } + const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); } virtual void collectPropertiesToImplement(PropertyMap &PM, PropertyDeclOrder &PO) const; + +void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, + ProtocolPropertyMap &PM) const; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCProtocol; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h b/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h index ca92040..42fe907 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h @@ -1,4 +1,4 @@ -//===--- OpenMP.h - Classes for representing OpenMP directives ---*- C++ -*-===// +//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief This file defines OpenMP nodes. +/// \brief This file defines OpenMP nodes for declarative directives. /// //===----------------------------------------------------------------------===// @@ -20,8 +20,6 @@ namespace clang { -class DeclRefExpr; - /// \brief This represents '#pragma omp threadprivate ...' directive. /// For example, in the following, both 'a' and 'A::b' are threadprivate: /// @@ -43,29 +41,29 @@ class OMPThreadPrivateDecl : public Decl { OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) : Decl(DK, DC, L), NumVars(0) { } - ArrayRef<const DeclRefExpr *> getVars() const { - return ArrayRef<const DeclRefExpr *>( - reinterpret_cast<const DeclRefExpr * const *>(this + 1), + ArrayRef<const Expr *> getVars() const { + return ArrayRef<const Expr *>( + reinterpret_cast<const Expr * const *>(this + 1), NumVars); } - llvm::MutableArrayRef<DeclRefExpr *> getVars() { - return llvm::MutableArrayRef<DeclRefExpr *>( - reinterpret_cast<DeclRefExpr **>(this + 1), + llvm::MutableArrayRef<Expr *> getVars() { + return llvm::MutableArrayRef<Expr *>( + reinterpret_cast<Expr **>(this + 1), NumVars); } - void setVars(ArrayRef<DeclRefExpr *> VL); + void setVars(ArrayRef<Expr *> VL); public: static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ArrayRef<DeclRefExpr *> VL); + ArrayRef<Expr *> VL); static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, unsigned ID, unsigned N); - typedef llvm::MutableArrayRef<DeclRefExpr *>::iterator varlist_iterator; - typedef ArrayRef<const DeclRefExpr *>::iterator varlist_const_iterator; + typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator; + typedef ArrayRef<const Expr *>::iterator varlist_const_iterator; unsigned varlist_size() const { return NumVars; } bool varlist_empty() const { return NumVars == 0; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h index 425a617..24bd28a 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h @@ -34,6 +34,8 @@ class TemplateTypeParmDecl; class NonTypeTemplateParmDecl; class TemplateTemplateParmDecl; class TypeAliasTemplateDecl; +class VarTemplateDecl; +class VarTemplatePartialSpecializationDecl; /// \brief Stores a template parameter of any kind. typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*, @@ -629,9 +631,9 @@ public: template <class decl_type> friend class RedeclarableTemplate; /// \brief Retrieves the canonical declaration of this template. - RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDeclaration(); } - const RedeclarableTemplateDecl *getCanonicalDecl() const { - return getFirstDeclaration(); + RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDecl(); } + const RedeclarableTemplateDecl *getCanonicalDecl() const { + return getFirstDecl(); } /// \brief Determines whether this template was a specialization of a @@ -713,6 +715,7 @@ public: using redeclarable_base::redecls_end; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -743,7 +746,7 @@ protected: /// \brief Data that is common to all of the declarations of a given /// function template. struct Common : CommonBase { - Common() : InjectedArgs(0) { } + Common() : InjectedArgs(), LazySpecializations() { } /// \brief The function template specializations for this function /// template, including explicit specializations and instantiations. @@ -757,6 +760,13 @@ protected: /// template, and is allocated lazily, since most function templates do not /// require the use of this information. TemplateArgument *InjectedArgs; + + /// \brief If non-null, points to an array of specializations known only + /// by their external declaration IDs. + /// + /// The first value in the array is the number of of specializations + /// that follow. + uint32_t *LazySpecializations; }; FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, @@ -771,12 +781,13 @@ protected: friend class FunctionDecl; + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + /// \brief Retrieve the set of function template specializations of this /// function template. llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & - getSpecializations() const { - return getCommonPtr()->Specializations; - } + getSpecializations() const; /// \brief Add a specialization of this function template. /// @@ -815,14 +826,14 @@ public: /// NULL if no such declaration exists. FunctionTemplateDecl *getPreviousDecl() { return cast_or_null<FunctionTemplateDecl>( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); } /// \brief Retrieve the previous declaration of this function template, or /// NULL if no such declaration exists. const FunctionTemplateDecl *getPreviousDecl() const { return cast_or_null<FunctionTemplateDecl>( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl()); } FunctionTemplateDecl *getInstantiatedFromMemberTemplate() { @@ -847,7 +858,7 @@ public: /// arguments for a function template, the notion is convenient when /// we need to perform substitutions inside the definition of a function /// template. - std::pair<const TemplateArgument *, unsigned> getInjectedTemplateArgs(); + ArrayRef<TemplateArgument> getInjectedTemplateArgs(); /// \brief Create a function template node. static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC, @@ -1377,7 +1388,7 @@ class ClassTemplateSpecializationDecl /// \brief The template argument list deduced for the class template /// partial specialization itself. - TemplateArgumentList *TemplateArgs; + const TemplateArgumentList *TemplateArgs; }; /// \brief The template that this specialization specializes @@ -1402,7 +1413,7 @@ class ClassTemplateSpecializationDecl ExplicitSpecializationInfo *ExplicitInfo; /// \brief The template arguments used to describe this specialization. - TemplateArgumentList *TemplateArgs; + const TemplateArgumentList *TemplateArgs; /// \brief The point where this template was instantiated (if any) SourceLocation PointOfInstantiation; @@ -1438,9 +1449,9 @@ public: bool Qualified) const; ClassTemplateSpecializationDecl *getMostRecentDecl() { - CXXRecordDecl *Recent - = cast<CXXRecordDecl>(CXXRecordDecl::getMostRecentDecl()); - if (!isa<ClassTemplateSpecializationDecl>(Recent)) { + CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>( + this)->getMostRecentDecl(); + while (!isa<ClassTemplateSpecializationDecl>(Recent)) { // FIXME: Does injected class name need to be in the redeclarations chain? assert(Recent->isInjectedClassName() && Recent->getPreviousDecl()); Recent = Recent->getPreviousDecl(); @@ -1553,7 +1564,7 @@ public: /// instantiation of the given class template partial specialization whose /// template arguments have been deduced. void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, - TemplateArgumentList *TemplateArgs) { + const TemplateArgumentList *TemplateArgs) { assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() && "Already set to a class template partial specialization!"); SpecializedPartialSpecialization *PS @@ -1639,13 +1650,7 @@ class ClassTemplatePartialSpecializationDecl /// \brief The source info for the template arguments as written. /// FIXME: redundant with TypeAsWritten? - TemplateArgumentLoc *ArgsAsWritten; - unsigned NumArgsAsWritten; - - /// \brief Sequence number indicating when this class template partial - /// specialization was added to the set of partial specializations for - /// its owning class template. - unsigned SequenceNumber; + const ASTTemplateArgumentListInfo *ArgsAsWritten; /// \brief The class template partial specialization from which this /// class template partial specialization was instantiated. @@ -1663,16 +1668,12 @@ class ClassTemplatePartialSpecializationDecl ClassTemplateDecl *SpecializedTemplate, const TemplateArgument *Args, unsigned NumArgs, - TemplateArgumentLoc *ArgInfos, - unsigned NumArgInfos, - ClassTemplatePartialSpecializationDecl *PrevDecl, - unsigned SequenceNumber); + const ASTTemplateArgumentListInfo *ArgsAsWritten, + ClassTemplatePartialSpecializationDecl *PrevDecl); ClassTemplatePartialSpecializationDecl() : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization), - TemplateParams(0), ArgsAsWritten(0), - NumArgsAsWritten(0), SequenceNumber(0), - InstantiatedFromMember(0, false) { } + TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { } public: static ClassTemplatePartialSpecializationDecl * @@ -1684,15 +1685,15 @@ public: unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos, QualType CanonInjectedType, - ClassTemplatePartialSpecializationDecl *PrevDecl, - unsigned SequenceNumber); + ClassTemplatePartialSpecializationDecl *PrevDecl); static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID); ClassTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast<ClassTemplatePartialSpecializationDecl>( - ClassTemplateSpecializationDecl::getMostRecentDecl()); + static_cast<ClassTemplateSpecializationDecl *>( + this)->getMostRecentDecl()); } /// Get the list of template parameters @@ -1701,19 +1702,10 @@ public: } /// Get the template arguments as written. - TemplateArgumentLoc *getTemplateArgsAsWritten() const { + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { return ArgsAsWritten; } - /// Get the number of template arguments as written. - unsigned getNumTemplateArgsAsWritten() const { - return NumArgsAsWritten; - } - - /// \brief Get the sequence number for this class template partial - /// specialization. - unsigned getSequenceNumber() const { return SequenceNumber; } - /// \brief Retrieve the member class template partial specialization from /// which this particular class template partial specialization was /// instantiated. @@ -1735,15 +1727,15 @@ public: /// \c Outer<float>::Inner<U*>, this function would return /// \c Outer<T>::Inner<U*>. ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() { - ClassTemplatePartialSpecializationDecl *First - = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration()); + ClassTemplatePartialSpecializationDecl *First = + cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); return First->InstantiatedFromMember.getPointer(); } void setInstantiatedFromMember( ClassTemplatePartialSpecializationDecl *PartialSpec) { - ClassTemplatePartialSpecializationDecl *First - = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration()); + ClassTemplatePartialSpecializationDecl *First = + cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); First->InstantiatedFromMember.setPointer(PartialSpec); } @@ -1764,15 +1756,15 @@ public: /// struct X<int>::Inner<T*> { /* ... */ }; /// \endcode bool isMemberSpecialization() { - ClassTemplatePartialSpecializationDecl *First - = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration()); + ClassTemplatePartialSpecializationDecl *First = + cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); return First->InstantiatedFromMember.getInt(); } /// \brief Note that this member template is a specialization. void setMemberSpecialization() { - ClassTemplatePartialSpecializationDecl *First - = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration()); + ClassTemplatePartialSpecializationDecl *First = + cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); assert(First->InstantiatedFromMember.getPointer() && "Only member templates can be member template specializations"); return First->InstantiatedFromMember.setInt(true); @@ -1821,7 +1813,7 @@ protected: QualType InjectedClassNameType; /// \brief If non-null, points to an array of specializations (including - /// partial specializations) known ownly by their external declaration IDs. + /// partial specializations) known only by their external declaration IDs. /// /// The first value in the array is the number of of specializations/ /// partial specializations that follow. @@ -1900,14 +1892,23 @@ public: /// NULL if no such declaration exists. ClassTemplateDecl *getPreviousDecl() { return cast_or_null<ClassTemplateDecl>( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); } /// \brief Retrieve the previous declaration of this class template, or /// NULL if no such declaration exists. const ClassTemplateDecl *getPreviousDecl() const { return cast_or_null<ClassTemplateDecl>( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast<const RedeclarableTemplateDecl *>( + this)->getPreviousDecl()); + } + + ClassTemplateDecl *getMostRecentDecl() { + return cast<ClassTemplateDecl>( + static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl()); + } + const ClassTemplateDecl *getMostRecentDecl() const { + return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl(); } ClassTemplateDecl *getInstantiatedFromMemberTemplate() { @@ -1926,11 +1927,6 @@ public: void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos); - /// \brief Return the next partial specialization sequence number. - unsigned getNextPartialSpecSequenceNumber() { - return getPartialSpecializations().size(); - } - /// \brief Retrieve the partial specializations as an ordered list. void getPartialSpecializations( SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS); @@ -2139,14 +2135,15 @@ public: /// NULL if no such declaration exists. TypeAliasTemplateDecl *getPreviousDecl() { return cast_or_null<TypeAliasTemplateDecl>( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); } /// \brief Retrieve the previous declaration of this function template, or /// NULL if no such declaration exists. const TypeAliasTemplateDecl *getPreviousDecl() const { return cast_or_null<TypeAliasTemplateDecl>( - RedeclarableTemplateDecl::getPreviousDecl()); + static_cast<const RedeclarableTemplateDecl *>( + this)->getPreviousDecl()); } TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() { @@ -2239,6 +2236,578 @@ public: inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD) : Function(FTD) { } +/// \brief Represents a variable template specialization, which refers to +/// a variable template with a given set of template arguments. +/// +/// Variable template specializations represent both explicit +/// specializations of variable templates, as in the example below, and +/// implicit instantiations of variable templates. +/// +/// \code +/// template<typename T> constexpr T pi = T(3.1415926535897932385); +/// +/// template<> +/// constexpr float pi<float>; // variable template specialization pi<float> +/// \endcode +class VarTemplateSpecializationDecl : public VarDecl, + public llvm::FoldingSetNode { + + /// \brief Structure that stores information about a variable template + /// specialization that was instantiated from a variable template partial + /// specialization. + struct SpecializedPartialSpecialization { + /// \brief The variable template partial specialization from which this + /// variable template specialization was instantiated. + VarTemplatePartialSpecializationDecl *PartialSpecialization; + + /// \brief The template argument list deduced for the variable template + /// partial specialization itself. + const TemplateArgumentList *TemplateArgs; + }; + + /// \brief The template that this specialization specializes. + llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *> + SpecializedTemplate; + + /// \brief Further info for explicit template specialization/instantiation. + struct ExplicitSpecializationInfo { + /// \brief The type-as-written. + TypeSourceInfo *TypeAsWritten; + /// \brief The location of the extern keyword. + SourceLocation ExternLoc; + /// \brief The location of the template keyword. + SourceLocation TemplateKeywordLoc; + + ExplicitSpecializationInfo() + : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {} + }; + + /// \brief Further info for explicit template specialization/instantiation. + /// Does not apply to implicit specializations. + ExplicitSpecializationInfo *ExplicitInfo; + + /// \brief The template arguments used to describe this specialization. + const TemplateArgumentList *TemplateArgs; + TemplateArgumentListInfo TemplateArgsInfo; + + /// \brief The point where this template was instantiated (if any). + SourceLocation PointOfInstantiation; + + /// \brief The kind of specialization this declaration refers to. + /// Really a value of type TemplateSpecializationKind. + unsigned SpecializationKind : 3; + +protected: + VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + VarTemplateDecl *SpecializedTemplate, + QualType T, TypeSourceInfo *TInfo, + StorageClass S, const TemplateArgument *Args, + unsigned NumArgs); + + explicit VarTemplateSpecializationDecl(Kind DK); + +public: + static VarTemplateSpecializationDecl * + Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, + TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, + unsigned NumArgs); + static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + + virtual void getNameForDiagnostic(raw_ostream &OS, + const PrintingPolicy &Policy, + bool Qualified) const; + + VarTemplateSpecializationDecl *getMostRecentDecl() { + VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl(); + return cast<VarTemplateSpecializationDecl>(Recent); + } + + /// \brief Retrieve the template that this specialization specializes. + VarTemplateDecl *getSpecializedTemplate() const; + + /// \brief Retrieve the template arguments of the variable template + /// specialization. + const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; } + + // TODO: Always set this when creating the new specialization? + void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo); + + const TemplateArgumentListInfo &getTemplateArgsInfo() const { + return TemplateArgsInfo; + } + + /// \brief Determine the kind of specialization that this + /// declaration represents. + TemplateSpecializationKind getSpecializationKind() const { + return static_cast<TemplateSpecializationKind>(SpecializationKind); + } + + bool isExplicitSpecialization() const { + return getSpecializationKind() == TSK_ExplicitSpecialization; + } + + /// \brief True if this declaration is an explicit specialization, + /// explicit instantiation declaration, or explicit instantiation + /// definition. + bool isExplicitInstantiationOrSpecialization() const { + switch (getTemplateSpecializationKind()) { + case TSK_ExplicitSpecialization: + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + return true; + + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + return false; + } + llvm_unreachable("bad template specialization kind"); + } + + void setSpecializationKind(TemplateSpecializationKind TSK) { + SpecializationKind = TSK; + } + + /// \brief Get the point of instantiation (if any), or null if none. + SourceLocation getPointOfInstantiation() const { + return PointOfInstantiation; + } + + void setPointOfInstantiation(SourceLocation Loc) { + assert(Loc.isValid() && "point of instantiation must be valid!"); + PointOfInstantiation = Loc; + } + + /// \brief If this variable template specialization is an instantiation of + /// a template (rather than an explicit specialization), return the + /// variable template or variable template partial specialization from which + /// it was instantiated. + llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> + getInstantiatedFrom() const { + if (getSpecializationKind() != TSK_ImplicitInstantiation && + getSpecializationKind() != TSK_ExplicitInstantiationDefinition && + getSpecializationKind() != TSK_ExplicitInstantiationDeclaration) + return llvm::PointerUnion<VarTemplateDecl *, + VarTemplatePartialSpecializationDecl *>(); + + if (SpecializedPartialSpecialization *PartialSpec = + SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) + return PartialSpec->PartialSpecialization; + + return SpecializedTemplate.get<VarTemplateDecl *>(); + } + + /// \brief Retrieve the variable template or variable template partial + /// specialization which was specialized by this. + llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> + getSpecializedTemplateOrPartial() const { + if (SpecializedPartialSpecialization *PartialSpec = + SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) + return PartialSpec->PartialSpecialization; + + return SpecializedTemplate.get<VarTemplateDecl *>(); + } + + /// \brief Retrieve the set of template arguments that should be used + /// to instantiate the initializer of the variable template or variable + /// template partial specialization from which this variable template + /// specialization was instantiated. + /// + /// \returns For a variable template specialization instantiated from the + /// primary template, this function will return the same template arguments + /// as getTemplateArgs(). For a variable template specialization instantiated + /// from a variable template partial specialization, this function will the + /// return deduced template arguments for the variable template partial + /// specialization itself. + const TemplateArgumentList &getTemplateInstantiationArgs() const { + if (SpecializedPartialSpecialization *PartialSpec = + SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) + return *PartialSpec->TemplateArgs; + + return getTemplateArgs(); + } + + /// \brief Note that this variable template specialization is actually an + /// instantiation of the given variable template partial specialization whose + /// template arguments have been deduced. + void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, + const TemplateArgumentList *TemplateArgs) { + assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() && + "Already set to a variable template partial specialization!"); + SpecializedPartialSpecialization *PS = + new (getASTContext()) SpecializedPartialSpecialization(); + PS->PartialSpecialization = PartialSpec; + PS->TemplateArgs = TemplateArgs; + SpecializedTemplate = PS; + } + + /// \brief Note that this variable template specialization is an instantiation + /// of the given variable template. + void setInstantiationOf(VarTemplateDecl *TemplDecl) { + assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() && + "Previously set to a variable template partial specialization!"); + SpecializedTemplate = TemplDecl; + } + + /// \brief Sets the type of this specialization as it was written by + /// the user. + void setTypeAsWritten(TypeSourceInfo *T) { + if (!ExplicitInfo) + ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; + ExplicitInfo->TypeAsWritten = T; + } + /// \brief Gets the type of this specialization as it was written by + /// the user, if it was so written. + TypeSourceInfo *getTypeAsWritten() const { + return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0; + } + + /// \brief Gets the location of the extern keyword, if present. + SourceLocation getExternLoc() const { + return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation(); + } + /// \brief Sets the location of the extern keyword. + void setExternLoc(SourceLocation Loc) { + if (!ExplicitInfo) + ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; + ExplicitInfo->ExternLoc = Loc; + } + + /// \brief Sets the location of the template keyword. + void setTemplateKeywordLoc(SourceLocation Loc) { + if (!ExplicitInfo) + ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; + ExplicitInfo->TemplateKeywordLoc = Loc; + } + /// \brief Gets the location of the template keyword, if present. + SourceLocation getTemplateKeywordLoc() const { + return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); + } + + void Profile(llvm::FoldingSetNodeID &ID) const { + Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, + const TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs, ASTContext &Context) { + ID.AddInteger(NumTemplateArgs); + for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg) + TemplateArgs[Arg].Profile(ID, Context); + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { + return K >= firstVarTemplateSpecialization && + K <= lastVarTemplateSpecialization; + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +class VarTemplatePartialSpecializationDecl + : public VarTemplateSpecializationDecl { + virtual void anchor(); + + /// \brief The list of template parameters + TemplateParameterList *TemplateParams; + + /// \brief The source info for the template arguments as written. + /// FIXME: redundant with TypeAsWritten? + const ASTTemplateArgumentListInfo *ArgsAsWritten; + + /// \brief The variable template partial specialization from which this + /// variable template partial specialization was instantiated. + /// + /// The boolean value will be true to indicate that this variable template + /// partial specialization was specialized at this level. + llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool> + InstantiatedFromMember; + + VarTemplatePartialSpecializationDecl( + ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, TemplateParameterList *Params, + VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, + StorageClass S, const TemplateArgument *Args, unsigned NumArgs, + const ASTTemplateArgumentListInfo *ArgInfos); + + VarTemplatePartialSpecializationDecl() + : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization), + TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {} + +public: + static VarTemplatePartialSpecializationDecl * + Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, TemplateParameterList *Params, + VarTemplateDecl *SpecializedTemplate, QualType T, + TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, + unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos); + + static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + + VarTemplatePartialSpecializationDecl *getMostRecentDecl() { + return cast<VarTemplatePartialSpecializationDecl>( + static_cast<VarTemplateSpecializationDecl *>( + this)->getMostRecentDecl()); + } + + /// Get the list of template parameters + TemplateParameterList *getTemplateParameters() const { + return TemplateParams; + } + + /// Get the template arguments as written. + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { + return ArgsAsWritten; + } + + /// \brief Retrieve the member variable template partial specialization from + /// which this particular variable template partial specialization was + /// instantiated. + /// + /// \code + /// template<typename T> + /// struct Outer { + /// template<typename U> U Inner; + /// template<typename U> U* Inner<U*> = (U*)(0); // #1 + /// }; + /// + /// template int* Outer<float>::Inner<int*>; + /// \endcode + /// + /// In this example, the instantiation of \c Outer<float>::Inner<int*> will + /// end up instantiating the partial specialization + /// \c Outer<float>::Inner<U*>, which itself was instantiated from the + /// variable template partial specialization \c Outer<T>::Inner<U*>. Given + /// \c Outer<float>::Inner<U*>, this function would return + /// \c Outer<T>::Inner<U*>. + VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() { + VarTemplatePartialSpecializationDecl *First = + cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); + return First->InstantiatedFromMember.getPointer(); + } + + void + setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) { + VarTemplatePartialSpecializationDecl *First = + cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); + First->InstantiatedFromMember.setPointer(PartialSpec); + } + + /// \brief Determines whether this variable template partial specialization + /// was a specialization of a member partial specialization. + /// + /// In the following example, the member template partial specialization + /// \c X<int>::Inner<T*> is a member specialization. + /// + /// \code + /// template<typename T> + /// struct X { + /// template<typename U> U Inner; + /// template<typename U> U* Inner<U*> = (U*)(0); + /// }; + /// + /// template<> template<typename T> + /// U* X<int>::Inner<T*> = (T*)(0) + 1; + /// \endcode + bool isMemberSpecialization() { + VarTemplatePartialSpecializationDecl *First = + cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); + return First->InstantiatedFromMember.getInt(); + } + + /// \brief Note that this member template is a specialization. + void setMemberSpecialization() { + VarTemplatePartialSpecializationDecl *First = + cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); + assert(First->InstantiatedFromMember.getPointer() && + "Only member templates can be member template specializations"); + return First->InstantiatedFromMember.setInt(true); + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { + return K == VarTemplatePartialSpecialization; + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// Declaration of a variable template. +class VarTemplateDecl : public RedeclarableTemplateDecl { + static void DeallocateCommon(void *Ptr); + +protected: + /// \brief Data that is common to all of the declarations of a given + /// variable template. + struct Common : CommonBase { + Common() : LazySpecializations() {} + + /// \brief The variable template specializations for this variable + /// template, including explicit specializations and instantiations. + llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations; + + /// \brief The variable template partial specializations for this variable + /// template. + llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> + PartialSpecializations; + + /// \brief If non-null, points to an array of specializations (including + /// partial specializations) known ownly by their external declaration IDs. + /// + /// The first value in the array is the number of of specializations/ + /// partial specializations that follow. + uint32_t *LazySpecializations; + }; + + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + + /// \brief Retrieve the set of specializations of this variable template. + llvm::FoldingSetVector<VarTemplateSpecializationDecl> & + getSpecializations() const; + + /// \brief Retrieve the set of partial specializations of this class + /// template. + llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & + getPartialSpecializations(); + + VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl) + : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {} + + VarTemplateDecl(EmptyShell Empty) + : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(), + DeclarationName(), 0, 0) {} + + CommonBase *newCommon(ASTContext &C) const; + + Common *getCommonPtr() const { + return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); + } + +public: + /// \brief Get the underlying variable declarations of the template. + VarDecl *getTemplatedDecl() const { + return static_cast<VarDecl *>(TemplatedDecl); + } + + /// \brief Returns whether this template declaration defines the primary + /// variable pattern. + bool isThisDeclarationADefinition() const { + return getTemplatedDecl()->isThisDeclarationADefinition(); + } + + VarTemplateDecl *getDefinition(); + + /// \brief Create a variable template node. + static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl, + VarTemplateDecl *PrevDecl); + + /// \brief Create an empty variable template node. + static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + /// \brief Return the specialization with the provided arguments if it exists, + /// otherwise return the insertion point. + VarTemplateSpecializationDecl * + findSpecialization(const TemplateArgument *Args, unsigned NumArgs, + void *&InsertPos); + + /// \brief Insert the specified specialization knowing that it is not already + /// in. InsertPos must be obtained from findSpecialization. + void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos); + + VarTemplateDecl *getCanonicalDecl() { + return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl()); + } + const VarTemplateDecl *getCanonicalDecl() const { + return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl()); + } + + /// \brief Retrieve the previous declaration of this variable template, or + /// NULL if no such declaration exists. + VarTemplateDecl *getPreviousDecl() { + return cast_or_null<VarTemplateDecl>( + static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); + } + + /// \brief Retrieve the previous declaration of this variable template, or + /// NULL if no such declaration exists. + const VarTemplateDecl *getPreviousDecl() const { + return cast_or_null<VarTemplateDecl>( + static_cast<const RedeclarableTemplateDecl *>( + this)->getPreviousDecl()); + } + + VarTemplateDecl *getInstantiatedFromMemberTemplate() { + return cast_or_null<VarTemplateDecl>( + RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); + } + + /// \brief Return the partial specialization with the provided arguments if it + /// exists, otherwise return the insertion point. + VarTemplatePartialSpecializationDecl * + findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs, + void *&InsertPos); + + /// \brief Insert the specified partial specialization knowing that it is not + /// already in. InsertPos must be obtained from findPartialSpecialization. + void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, + void *InsertPos); + + /// \brief Retrieve the partial specializations as an ordered list. + void getPartialSpecializations( + SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS); + + /// \brief Find a variable template partial specialization which was + /// instantiated + /// from the given member partial specialization. + /// + /// \param D a member variable template partial specialization. + /// + /// \returns the variable template partial specialization which was + /// instantiated + /// from the given member partial specialization, or NULL if no such partial + /// specialization exists. + VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember( + VarTemplatePartialSpecializationDecl *D); + + typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator; + + spec_iterator spec_begin() const { + return makeSpecIterator(getSpecializations(), false); + } + + spec_iterator spec_end() const { + return makeSpecIterator(getSpecializations(), true); + } + + typedef SpecIterator<VarTemplatePartialSpecializationDecl> + partial_spec_iterator; + + partial_spec_iterator partial_spec_begin() { + return makeSpecIterator(getPartialSpecializations(), false); + } + + partial_spec_iterator partial_spec_end() { + return makeSpecIterator(getPartialSpecializations(), true); + } + + // Implement isa/cast/dyncast support + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == VarTemplate; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + } /* end of namespace clang */ #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h index f28882b..00766c2 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclarationName.h @@ -182,11 +182,16 @@ public: // operator bool() - Evaluates true when this declaration name is // non-empty. - operator bool() const { + LLVM_EXPLICIT operator bool() const { return ((Ptr & PtrMask) != 0) || (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask)); } + /// \brief Evaluates true when this declaration name is empty. + bool isEmpty() const { + return !*this; + } + /// Predicate functions for querying what type of name this is. bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; } bool isObjCZeroArgSelector() const { @@ -210,9 +215,6 @@ public: /// getNameAsString - Retrieve the human-readable string for this name. std::string getAsString() const; - /// printName - Print the human-readable name to a stream. - void printName(raw_ostream &OS) const; - /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in /// this declaration name, or NULL if this declaration name isn't a /// simple identifier. @@ -302,6 +304,8 @@ public: void dump() const; }; +raw_ostream &operator<<(raw_ostream &OS, DeclarationName N); + /// Ordering on two declaration names. If both names are identifiers, /// this provides a lexicographical ordering. inline bool operator<(DeclarationName LHS, DeclarationName RHS) { diff --git a/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h index 2e3cbfa..12c4fcc 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h @@ -53,7 +53,7 @@ public: if (E->getCond()->isValueDependent()) return; // Only the selected subexpression matters; the other one is not evaluated. - return this->Visit(E->getChosenSubExpr(Context)); + return this->Visit(E->getChosenSubExpr()); } void VisitDesignatedInitExpr(DesignatedInitExpr *E) { diff --git a/contrib/llvm/tools/clang/include/clang/AST/Expr.h b/contrib/llvm/tools/clang/include/clang/AST/Expr.h index 4ff1257..f2648b9 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Expr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Expr.h @@ -277,7 +277,6 @@ public: MLV_IncompleteType, MLV_ConstQualified, MLV_ArrayType, - MLV_ReadonlyProperty, MLV_NoSetterProperty, MLV_MemberFunction, MLV_SubObjCPropertySetting, @@ -483,21 +482,22 @@ public: /// /// Note: This does not perform the implicit conversions required by C++11 /// [expr.const]p5. - bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, + bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc = 0, bool isEvaluated = true) const; - bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const; + bool isIntegerConstantExpr(const ASTContext &Ctx, + SourceLocation *Loc = 0) const; /// isCXX98IntegralConstantExpr - Return true if this expression is an /// integral constant expression in C++98. Can only be used in C++. - bool isCXX98IntegralConstantExpr(ASTContext &Ctx) const; + bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const; /// isCXX11ConstantExpr - Return true if this expression is a constant /// expression in C++11. Can only be used in C++. /// /// Note: This does not perform the implicit conversions required by C++11 /// [expr.const]p5. - bool isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result = 0, + bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = 0, SourceLocation *Loc = 0) const; /// isPotentialConstantExpr - Return true if this function's definition @@ -579,15 +579,14 @@ public: /// \brief Determine whether this expression involves a call to any function /// that is not trivial. bool hasNonTrivialCall(ASTContext &Ctx); - + /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded /// integer. This must be called on an expression that constant folds to an /// integer. llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl<PartialDiagnosticAt> *Diag=0) const; - - void EvaluateForOverflow(const ASTContext &Ctx, - SmallVectorImpl<PartialDiagnosticAt> *Diag) const; + + void EvaluateForOverflow(const ASTContext &Ctx) const; /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an /// lvalue with link time known address, with no side-effects. @@ -760,10 +759,10 @@ public: /// 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; + /// the LHSs of comma expressions and adjustments needed along the path. + const Expr *skipRValueSubobjectAdjustments( + SmallVectorImpl<const Expr *> &CommaLHS, + SmallVectorImpl<SubobjectAdjustment> &Adjustments) const; /// Skip irrelevant expressions to find what should be materialize for /// binding with a reference. @@ -893,7 +892,7 @@ class DeclRefExpr : public Expr { bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; } /// \brief Helper to retrieve the optional NamedDecl through which this - /// reference occured. + /// reference occurred. NamedDecl *&getInternalFoundDecl() { assert(hasFoundDecl()); if (hasQualifier()) @@ -902,12 +901,12 @@ class DeclRefExpr : public Expr { } /// \brief Helper to retrieve the optional NamedDecl through which this - /// reference occured. + /// reference occurred. NamedDecl *getInternalFoundDecl() const { return const_cast<DeclRefExpr *>(this)->getInternalFoundDecl(); } - DeclRefExpr(ASTContext &Ctx, + DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool refersToEnclosingLocal, @@ -922,7 +921,7 @@ class DeclRefExpr : public Expr { /// \brief Computes the type- and value-dependence flags for this /// declaration reference expression. - void computeDependence(ASTContext &C); + void computeDependence(const ASTContext &C); public: DeclRefExpr(ValueDecl *D, bool refersToEnclosingLocal, QualType T, @@ -938,7 +937,7 @@ public: computeDependence(D->getASTContext()); } - static DeclRefExpr *Create(ASTContext &Context, + static DeclRefExpr *Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, @@ -948,7 +947,7 @@ public: NamedDecl *FoundD = 0, const TemplateArgumentListInfo *TemplateArgs = 0); - static DeclRefExpr *Create(ASTContext &Context, + static DeclRefExpr *Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, @@ -959,7 +958,7 @@ public: const TemplateArgumentListInfo *TemplateArgs = 0); /// \brief Construct an empty declaration reference expression. - static DeclRefExpr *CreateEmpty(ASTContext &Context, + static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier, bool HasFoundDecl, bool HasTemplateKWAndArgsInfo, @@ -1000,7 +999,7 @@ public: return getInternalQualifierLoc(); } - /// \brief Get the NamedDecl through which this reference occured. + /// \brief Get the NamedDecl through which this reference occurred. /// /// This Decl may be different from the ValueDecl actually referred to in the /// presence of using declarations, etc. It always returns non-NULL, and may @@ -1151,6 +1150,7 @@ public: Func, Function, LFunction, // Same as Function, but as wide string. + FuncDName, PrettyFunction, /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the /// 'virtual' keyword is omitted for virtual member functions. @@ -1221,13 +1221,15 @@ protected: else return llvm::APInt(BitWidth, VAL); } - void setIntValue(ASTContext &C, const llvm::APInt &Val); + void setIntValue(const ASTContext &C, const llvm::APInt &Val); }; class APIntStorage : private APNumericStorage { public: llvm::APInt getValue() const { return getIntValue(); } - void setValue(ASTContext &C, const llvm::APInt &Val) { setIntValue(C, Val); } + void setValue(const ASTContext &C, const llvm::APInt &Val) { + setIntValue(C, Val); + } }; class APFloatStorage : private APNumericStorage { @@ -1235,7 +1237,7 @@ public: llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const { return llvm::APFloat(Semantics, getIntValue()); } - void setValue(ASTContext &C, const llvm::APFloat &Val) { + void setValue(const ASTContext &C, const llvm::APFloat &Val) { setIntValue(C, Val.bitcastToAPInt()); } }; @@ -1250,17 +1252,17 @@ class IntegerLiteral : public Expr, public APIntStorage { public: // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, // or UnsignedLongLongTy - IntegerLiteral(ASTContext &C, const llvm::APInt &V, QualType type, + IntegerLiteral(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l); /// \brief Returns a new integer literal with value 'V' and type 'type'. /// \param type - either IntTy, LongTy, LongLongTy, UnsignedIntTy, /// UnsignedLongTy, or UnsignedLongLongTy which should match the size of V /// \param V - the value that the returned integer literal contains. - static IntegerLiteral *Create(ASTContext &C, const llvm::APInt &V, + static IntegerLiteral *Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l); /// \brief Returns a new empty integer literal. - static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty); + static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty); SourceLocation getLocStart() const LLVM_READONLY { return Loc; } SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } @@ -1328,21 +1330,21 @@ public: class FloatingLiteral : public Expr, private APFloatStorage { SourceLocation Loc; - FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, + FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L); /// \brief Construct an empty floating-point literal. - explicit FloatingLiteral(ASTContext &C, EmptyShell Empty); + explicit FloatingLiteral(const ASTContext &C, EmptyShell Empty); public: - static FloatingLiteral *Create(ASTContext &C, const llvm::APFloat &V, + static FloatingLiteral *Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L); - static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty); + static FloatingLiteral *Create(const ASTContext &C, EmptyShell Empty); llvm::APFloat getValue() const { return APFloatStorage::getValue(getSemantics()); } - void setValue(ASTContext &C, const llvm::APFloat &Val) { + void setValue(const ASTContext &C, const llvm::APFloat &Val) { assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics"); APFloatStorage::setValue(C, Val); } @@ -1420,7 +1422,7 @@ public: }; /// StringLiteral - This represents a string literal expression, e.g. "foo" -/// or L"bar" (wide strings). The actual string is returned by getStrData() +/// or L"bar" (wide strings). The actual string is returned by getBytes() /// is NOT null-terminated, and the length of the string is determined by /// calling getByteLength(). The C type for a string is always a /// ConstantArrayType. In C++, the char type is const qualified, in C it is @@ -1469,19 +1471,19 @@ private: public: /// This is the "fully general" constructor that allows representation of /// strings formed from multiple concatenated tokens. - static StringLiteral *Create(ASTContext &C, StringRef Str, StringKind Kind, - bool Pascal, QualType Ty, + static StringLiteral *Create(const ASTContext &C, StringRef Str, + StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs); /// Simple constructor for string literals made from one token. - static StringLiteral *Create(ASTContext &C, StringRef Str, StringKind Kind, - bool Pascal, QualType Ty, + static StringLiteral *Create(const ASTContext &C, StringRef Str, + StringKind Kind, bool Pascal, QualType Ty, SourceLocation Loc) { return Create(C, Str, Kind, Pascal, Ty, &Loc, 1); } /// \brief Construct an empty string literal. - static StringLiteral *CreateEmpty(ASTContext &C, unsigned NumStrs); + static StringLiteral *CreateEmpty(const ASTContext &C, unsigned NumStrs); StringRef getString() const { assert(CharByteWidth==1 @@ -1520,7 +1522,7 @@ public: unsigned getCharByteWidth() const { return CharByteWidth; } /// \brief Sets the string data to the given string data. - void setString(ASTContext &C, StringRef Str, + void setString(const ASTContext &C, StringRef Str, StringKind Kind, bool IsPascal); StringKind getKind() const { return static_cast<StringKind>(Kind); } @@ -1853,7 +1855,7 @@ private: // Number of sub-expressions (i.e. array subscript expressions). unsigned NumExprs; - OffsetOfExpr(ASTContext &C, QualType type, + OffsetOfExpr(const ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs, SourceLocation RParenLoc); @@ -1864,12 +1866,12 @@ private: public: - static OffsetOfExpr *Create(ASTContext &C, QualType type, + static OffsetOfExpr *Create(const ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs, SourceLocation RParenLoc); - static OffsetOfExpr *CreateEmpty(ASTContext &C, + static OffsetOfExpr *CreateEmpty(const ASTContext &C, unsigned NumComps, unsigned NumExprs); /// getOperatorLoc - Return the location of the operator. @@ -2133,10 +2135,11 @@ class CallExpr : public Expr { protected: // These versions of the constructor are for derived classes. - CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, + CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation rparenloc); - CallExpr(ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty); + CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs, + EmptyShell Empty); Stmt *getPreArg(unsigned i) { assert(i < getNumPreArgs() && "Prearg access out of range!"); @@ -2154,11 +2157,11 @@ protected: unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; } public: - CallExpr(ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t, + CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation rparenloc); /// \brief Build an empty call expression. - CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty); + CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty); const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); } Expr *getCallee() { return cast<Expr>(SubExprs[FN]); } @@ -2206,7 +2209,7 @@ public: /// setNumArgs - This changes the number of arguments present in this call. /// Any orphaned expressions are deleted by this, and any new operands are set /// to null. - void setNumArgs(ASTContext& C, unsigned NumArgs); + void setNumArgs(const ASTContext& C, unsigned NumArgs); typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; @@ -2360,7 +2363,7 @@ public: HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) {} - static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow, + static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *memberdecl, DeclAccessPair founddecl, @@ -2747,12 +2750,13 @@ public: : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) { } - static ImplicitCastExpr *Create(ASTContext &Context, QualType T, + static ImplicitCastExpr *Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat); - static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize); + static ImplicitCastExpr *CreateEmpty(const ASTContext &Context, + unsigned PathSize); SourceLocation getLocStart() const LLVM_READONLY { return getSubExpr()->getLocStart(); @@ -2838,13 +2842,14 @@ class CStyleCastExpr : public ExplicitCastExpr { : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { } public: - static CStyleCastExpr *Create(ASTContext &Context, QualType T, + static CStyleCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R); - static CStyleCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize); + static CStyleCastExpr *CreateEmpty(const ASTContext &Context, + unsigned PathSize); SourceLocation getLParenLoc() const { return LPLoc; } void setLParenLoc(SourceLocation L) { LPLoc = L; } @@ -3412,7 +3417,7 @@ class ShuffleVectorExpr : public Expr { unsigned NumExprs; public: - ShuffleVectorExpr(ASTContext &C, ArrayRef<Expr*> args, QualType Type, + ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type, SourceLocation BLoc, SourceLocation RP); /// \brief Build an empty vector-shuffle expression. @@ -3450,11 +3455,11 @@ public: return cast<Expr>(SubExprs[Index]); } - void setExprs(ASTContext &C, Expr ** Exprs, unsigned NumExprs); + void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs); - unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) const { + llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const { assert((N < NumExprs - 2) && "Shuffle idx out of range!"); - return getExpr(N+2)->EvaluateKnownConstInt(Ctx).getZExtValue(); + return getExpr(N+2)->EvaluateKnownConstInt(Ctx); } // Iterators @@ -3463,6 +3468,60 @@ public: } }; +/// ConvertVectorExpr - Clang builtin function __builtin_convertvector +/// This AST node provides support for converting a vector type to another +/// vector type of the same arity. +class ConvertVectorExpr : public Expr { +private: + Stmt *SrcExpr; + TypeSourceInfo *TInfo; + SourceLocation BuiltinLoc, RParenLoc; + + friend class ASTReader; + friend class ASTStmtReader; + explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {} + +public: + ConvertVectorExpr(Expr* SrcExpr, TypeSourceInfo *TI, QualType DstType, + ExprValueKind VK, ExprObjectKind OK, + SourceLocation BuiltinLoc, SourceLocation RParenLoc) + : Expr(ConvertVectorExprClass, DstType, VK, OK, + DstType->isDependentType(), + DstType->isDependentType() || SrcExpr->isValueDependent(), + (DstType->isInstantiationDependentType() || + SrcExpr->isInstantiationDependent()), + (DstType->containsUnexpandedParameterPack() || + SrcExpr->containsUnexpandedParameterPack())), + SrcExpr(SrcExpr), TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} + + /// getSrcExpr - Return the Expr to be converted. + Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); } + + /// getTypeSourceInfo - Return the destination type. + TypeSourceInfo *getTypeSourceInfo() const { + return TInfo; + } + void setTypeSourceInfo(TypeSourceInfo *ti) { + TInfo = ti; + } + + /// getBuiltinLoc - Return the location of the __builtin_convertvector token. + SourceLocation getBuiltinLoc() const { return BuiltinLoc; } + + /// getRParenLoc - Return the location of final right parenthesis. + SourceLocation getRParenLoc() const { return RParenLoc; } + + SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ConvertVectorExprClass; + } + + // Iterators + child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } +}; + /// ChooseExpr - GNU builtin-in function __builtin_choose_expr. /// This AST node is similar to the conditional operator (?:) in C, with /// the following exceptions: @@ -3476,10 +3535,12 @@ class ChooseExpr : public Expr { enum { COND, LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. SourceLocation BuiltinLoc, RParenLoc; + bool CondIsTrue; public: ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK, ExprObjectKind OK, - SourceLocation RP, bool TypeDependent, bool ValueDependent) + SourceLocation RP, bool condIsTrue, + bool TypeDependent, bool ValueDependent) : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent, (cond->isInstantiationDependent() || lhs->isInstantiationDependent() || @@ -3487,7 +3548,7 @@ public: (cond->containsUnexpandedParameterPack() || lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), - BuiltinLoc(BLoc), RParenLoc(RP) { + BuiltinLoc(BLoc), RParenLoc(RP), CondIsTrue(condIsTrue) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -3498,12 +3559,21 @@ public: /// isConditionTrue - Return whether the condition is true (i.e. not /// equal to zero). - bool isConditionTrue(const ASTContext &C) const; + bool isConditionTrue() const { + assert(!isConditionDependent() && + "Dependent condition isn't true or false"); + return CondIsTrue; + } + void setIsConditionTrue(bool isTrue) { CondIsTrue = isTrue; } + + bool isConditionDependent() const { + return getCond()->isTypeDependent() || getCond()->isValueDependent(); + } /// getChosenSubExpr - Return the subexpression chosen according to the /// condition. - Expr *getChosenSubExpr(const ASTContext &C) const { - return isConditionTrue(C) ? getLHS() : getRHS(); + Expr *getChosenSubExpr() const { + return isConditionTrue() ? getLHS() : getRHS(); } Expr *getCond() const { return cast<Expr>(SubExprs[COND]); } @@ -3663,7 +3733,7 @@ class InitListExpr : public Expr { SourceLocation LBraceLoc, RBraceLoc; /// The alternative form of the initializer list (if it exists). - /// The int part of the pair stores whether this initalizer list is + /// The int part of the pair stores whether this initializer 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. @@ -3679,7 +3749,7 @@ class InitListExpr : public Expr { llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit; public: - InitListExpr(ASTContext &C, SourceLocation lbraceloc, + InitListExpr(const ASTContext &C, SourceLocation lbraceloc, ArrayRef<Expr*> initExprs, SourceLocation rbraceloc); /// \brief Build an empty initializer list. @@ -3707,7 +3777,7 @@ public: } /// \brief Reserve space for some number of initializers. - void reserveInits(ASTContext &C, unsigned NumInits); + void reserveInits(const ASTContext &C, unsigned NumInits); /// @brief Specify the number of initializers /// @@ -3715,7 +3785,7 @@ public: /// initializers will be destroyed. If there are fewer than @p /// NumInits initializers, NULL expressions will be added for the /// unknown initializers. - void resizeInits(ASTContext &Context, unsigned NumInits); + void resizeInits(const ASTContext &Context, unsigned NumInits); /// @brief Updates the initializer at index @p Init with the new /// expression @p expr, and returns the old expression at that @@ -3724,7 +3794,7 @@ public: /// When @p Init is out of range for this initializer list, the /// initializer list will be extended with NULL expressions to /// accommodate the new entry. - Expr *updateInit(ASTContext &C, unsigned Init, Expr *expr); + Expr *updateInit(const ASTContext &C, unsigned Init, Expr *expr); /// \brief If this initializer list initializes an array with more elements /// than there are initializers in the list, specifies an expression to be @@ -3754,6 +3824,10 @@ public: return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion(); } void setInitializedFieldInUnion(FieldDecl *FD) { + assert((FD == 0 + || getInitializedFieldInUnion() == 0 + || getInitializedFieldInUnion() == FD) + && "Only one field of a union may be initialized at a time!"); ArrayFillerOrUnionFieldInit = FD; } @@ -3794,13 +3868,6 @@ public: InitListExprBits.HadArrayRangeDesignator = ARD; } - bool initializesStdInitializerList() const { - return InitListExprBits.InitializesStdInitializerList != 0; - } - void setInitializesStdInitializerList(bool ISIL = true) { - InitListExprBits.InitializesStdInitializerList = ISIL; - } - SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; @@ -3851,7 +3918,7 @@ public: /// The InitListExpr contains three DesignatedInitExprs, the first of /// which covers @c [2].y=1.0. This DesignatedInitExpr will have two /// designators, one array designator for @c [2] followed by one field -/// designator for @c .y. The initalization expression will be 1.0. +/// designator for @c .y. The initialization expression will be 1.0. class DesignatedInitExpr : public Expr { public: /// \brief Forward declaration of the Designator class. @@ -3879,7 +3946,7 @@ private: Designator *Designators; - DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumDesignators, + DesignatedInitExpr(const ASTContext &C, QualType Ty, unsigned NumDesignators, const Designator *Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, ArrayRef<Expr*> IndexExprs, Expr *Init); @@ -4041,13 +4108,15 @@ public: } }; - static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators, + static DesignatedInitExpr *Create(const ASTContext &C, + Designator *Designators, unsigned NumDesignators, ArrayRef<Expr*> IndexExprs, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr *Init); - static DesignatedInitExpr *CreateEmpty(ASTContext &C, unsigned NumIndexExprs); + static DesignatedInitExpr *CreateEmpty(const ASTContext &C, + unsigned NumIndexExprs); /// @brief Returns the number of designators in this initializer. unsigned size() const { return NumDesignators; } @@ -4085,7 +4154,7 @@ public: Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; } - void setDesignators(ASTContext &C, const Designator *Desigs, + void setDesignators(const ASTContext &C, const Designator *Desigs, unsigned NumDesigs); Expr *getArrayIndex(const Designator &D) const; @@ -4133,8 +4202,8 @@ public: /// \brief Replaces the designator at index @p Idx with the series /// of designators in [First, Last). - void ExpandDesignator(ASTContext &C, unsigned Idx, const Designator *First, - const Designator *Last); + void ExpandDesignator(const ASTContext &C, unsigned Idx, + const Designator *First, const Designator *Last); SourceRange getDesignatorsSourceRange() const; @@ -4188,8 +4257,8 @@ class ParenListExpr : public Expr { SourceLocation LParenLoc, RParenLoc; public: - ParenListExpr(ASTContext& C, SourceLocation lparenloc, ArrayRef<Expr*> exprs, - SourceLocation rparenloc); + ParenListExpr(const ASTContext& C, SourceLocation lparenloc, + ArrayRef<Expr*> exprs, SourceLocation rparenloc); /// \brief Build an empty paren list. explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } @@ -4262,7 +4331,7 @@ class GenericSelectionExpr : public Expr { SourceLocation GenericLoc, DefaultLoc, RParenLoc; public: - GenericSelectionExpr(ASTContext &Context, + GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef<TypeSourceInfo*> AssocTypes, ArrayRef<Expr*> AssocExprs, @@ -4271,7 +4340,7 @@ public: unsigned ResultIndex); /// This constructor is used in the result-dependent case. - GenericSelectionExpr(ASTContext &Context, + GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef<TypeSourceInfo*> AssocTypes, ArrayRef<Expr*> AssocExprs, @@ -4450,7 +4519,7 @@ public: /// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] /// This AST node provides support for reinterpreting a type to another /// type of the same size. -class AsTypeExpr : public Expr { // Should this be an ExplicitCastExpr? +class AsTypeExpr : public Expr { private: Stmt *SrcExpr; SourceLocation BuiltinLoc, RParenLoc; @@ -4552,13 +4621,13 @@ class PseudoObjectExpr : public Expr { public: /// NoResult - A value for the result index indicating that there is /// no semantic result. - enum { NoResult = ~0U }; + enum LLVM_ENUM_INT_TYPE(unsigned) { NoResult = ~0U }; - static PseudoObjectExpr *Create(ASTContext &Context, Expr *syntactic, + static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic, ArrayRef<Expr*> semantic, unsigned resultIndex); - static PseudoObjectExpr *Create(ASTContext &Context, EmptyShell shell, + static PseudoObjectExpr *Create(const ASTContext &Context, EmptyShell shell, unsigned numSemanticExprs); /// Return the syntactic form of this expression, i.e. the diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h index 91e5b21..6356ee7 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h @@ -6,9 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the Expr interface and subclasses for C++ expressions. -// +/// +/// \file +/// \brief Defines the clang::Expr interface and subclasses for C++ expressions. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_EXPRCXX_H @@ -74,15 +75,15 @@ public: CallExpr(C, CXXOperatorCallExprClass, Empty) { } - /// getOperator - Returns the kind of overloaded operator that this + /// \brief Returns the kind of overloaded operator that this /// expression refers to. OverloadedOperatorKind getOperator() const { return Operator; } - /// getOperatorLoc - Returns the location of the operator symbol in - /// the expression. When @c getOperator()==OO_Call, this is the - /// location of the right parentheses; when @c - /// getOperator()==OO_Subscript, this is the location of the right - /// bracket. + /// \brief Returns the location of the operator symbol in the expression. + /// + /// When \c getOperator()==OO_Call, this is the location of the right + /// parentheses; when \c getOperator()==OO_Subscript, this is the location + /// of the right bracket. SourceLocation getOperatorLoc() const { return getRParenLoc(); } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } @@ -105,7 +106,7 @@ public: friend class ASTStmtWriter; }; -/// CXXMemberCallExpr - Represents a call to a member function that +/// Represents a call to a member function that /// may be written either with member call syntax (e.g., "obj.func()" /// or "objptr->func()") or with normal function-call syntax /// ("func()") within a member function that ends up calling a member @@ -122,18 +123,19 @@ public: CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CXXMemberCallExprClass, Empty) { } - /// getImplicitObjectArgument - Retrieves the implicit object - /// argument for the member call. For example, in "x.f(5)", this - /// operation would return "x". + /// \brief Retrieves the implicit object argument for the member call. + /// + /// For example, in "x.f(5)", this returns the sub-expression "x". Expr *getImplicitObjectArgument() const; - /// Retrieves the declaration of the called method. + /// \brief Retrieves the declaration of the called method. CXXMethodDecl *getMethodDecl() const; - /// getRecordDecl - Retrieves the CXXRecordDecl for the underlying type of - /// the implicit object argument. Note that this is may not be the same - /// declaration as that of the class context of the CXXMethodDecl which this - /// function is calling. + /// \brief Retrieves the CXXRecordDecl for the underlying type of + /// the implicit object argument. + /// + /// Note that this is may not be the same declaration as that of the class + /// context of the CXXMethodDecl which this function is calling. /// FIXME: Returns 0 for member pointer call exprs. CXXRecordDecl *getRecordDecl() const; @@ -142,7 +144,7 @@ public: } }; -/// CUDAKernelCallExpr - Represents a call to a CUDA kernel function. +/// \brief Represents a call to a CUDA kernel function. class CUDAKernelCallExpr : public CallExpr { private: enum { CONFIG, END_PREARG }; @@ -169,13 +171,12 @@ public: } }; -/// CXXNamedCastExpr - Abstract class common to all of the C++ "named" -/// casts, @c static_cast, @c dynamic_cast, @c reinterpret_cast, or @c -/// const_cast. +/// \brief Abstract class common to all of the C++ "named"/"keyword" casts. /// /// This abstract class is inherited by all of the classes -/// representing "named" casts, e.g., CXXStaticCastExpr, -/// CXXDynamicCastExpr, CXXReinterpretCastExpr, and CXXConstCastExpr. +/// representing "named" casts: CXXStaticCastExpr for \c static_cast, +/// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for +/// reinterpret_cast, and CXXConstCastExpr for \c const_cast. class CXXNamedCastExpr : public ExplicitCastExpr { private: SourceLocation Loc; // the location of the casting op @@ -200,7 +201,7 @@ public: const char *getCastName() const; /// \brief Retrieve the location of the cast operator keyword, e.g., - /// "static_cast". + /// \c static_cast. SourceLocation getOperatorLoc() const { return Loc; } /// \brief Retrieve the location of the closing parenthesis. @@ -223,11 +224,10 @@ public: } }; -/// CXXStaticCastExpr - A C++ @c static_cast expression -/// (C++ [expr.static.cast]). +/// \brief A C++ \c static_cast expression (C++ [expr.static.cast]). /// /// This expression node represents a C++ static cast, e.g., -/// @c static_cast<int>(1.0). +/// \c static_cast<int>(1.0). class CXXStaticCastExpr : public CXXNamedCastExpr { CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, @@ -240,13 +240,13 @@ class CXXStaticCastExpr : public CXXNamedCastExpr { : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { } public: - static CXXStaticCastExpr *Create(ASTContext &Context, QualType T, + static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets); - static CXXStaticCastExpr *CreateEmpty(ASTContext &Context, + static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context, unsigned PathSize); static bool classof(const Stmt *T) { @@ -254,12 +254,11 @@ public: } }; -/// CXXDynamicCastExpr - A C++ @c dynamic_cast expression -/// (C++ [expr.dynamic.cast]), which may perform a run-time check to -/// determine how to perform the type cast. +/// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]). /// /// This expression node represents a dynamic cast, e.g., -/// @c dynamic_cast<Derived*>(BasePtr). +/// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time +/// check to determine how to perform the type conversion. class CXXDynamicCastExpr : public CXXNamedCastExpr { CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, @@ -272,14 +271,14 @@ class CXXDynamicCastExpr : public CXXNamedCastExpr { : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { } public: - static CXXDynamicCastExpr *Create(ASTContext &Context, QualType T, + static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets); - static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context, + static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context, unsigned pathSize); bool isAlwaysNull() const; @@ -289,12 +288,14 @@ public: } }; -/// CXXReinterpretCastExpr - A C++ @c reinterpret_cast expression (C++ -/// [expr.reinterpret.cast]), which provides a differently-typed view -/// of a value but performs no actual work at run time. +/// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]). /// /// This expression node represents a reinterpret cast, e.g., /// @c reinterpret_cast<int>(VoidPtr). +/// +/// A reinterpret_cast provides a differently-typed view of a value but +/// (in Clang, as in most C++ implementations) performs no actual work at +/// run time. class CXXReinterpretCastExpr : public CXXNamedCastExpr { CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, unsigned pathSize, @@ -308,13 +309,13 @@ class CXXReinterpretCastExpr : public CXXNamedCastExpr { : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { } public: - static CXXReinterpretCastExpr *Create(ASTContext &Context, QualType T, + static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets); - static CXXReinterpretCastExpr *CreateEmpty(ASTContext &Context, + static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context, unsigned pathSize); static bool classof(const Stmt *T) { @@ -322,11 +323,13 @@ public: } }; -/// CXXConstCastExpr - A C++ @c const_cast expression (C++ [expr.const.cast]), -/// which can remove type qualifiers but does not change the underlying value. +/// \brief A C++ \c const_cast expression (C++ [expr.const.cast]). /// /// This expression node represents a const cast, e.g., -/// @c const_cast<char*>(PtrToConstChar). +/// \c const_cast<char*>(PtrToConstChar). +/// +/// A const_cast can remove type qualifiers but does not change the underlying +/// value. class CXXConstCastExpr : public CXXNamedCastExpr { CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op, TypeSourceInfo *writtenTy, SourceLocation l, @@ -338,19 +341,19 @@ class CXXConstCastExpr : public CXXNamedCastExpr { : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { } public: - static CXXConstCastExpr *Create(ASTContext &Context, QualType T, + static CXXConstCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets); - static CXXConstCastExpr *CreateEmpty(ASTContext &Context); + static CXXConstCastExpr *CreateEmpty(const ASTContext &Context); static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstCastExprClass; } }; -/// UserDefinedLiteral - A call to a literal operator (C++11 [over.literal]) +/// \brief A call to a literal operator (C++11 [over.literal]) /// written as a user-defined literal (C++11 [lit.ext]). /// /// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this @@ -364,12 +367,12 @@ class UserDefinedLiteral : public CallExpr { SourceLocation UDSuffixLoc; public: - UserDefinedLiteral(ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args, + UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args, QualType T, ExprValueKind VK, SourceLocation LitEndLoc, SourceLocation SuffixLoc) : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc), UDSuffixLoc(SuffixLoc) {} - explicit UserDefinedLiteral(ASTContext &C, EmptyShell Empty) + explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty) : CallExpr(C, UserDefinedLiteralClass, Empty) {} /// The kind of literal operator which is invoked. @@ -382,11 +385,11 @@ public: LOK_Character ///< operator "" X (CharT) }; - /// getLiteralOperatorKind - Returns the kind of literal operator invocation + /// \brief Returns the kind of literal operator invocation /// which this expression represents. LiteralOperatorKind getLiteralOperatorKind() const; - /// getCookedLiteral - If this is not a raw user-defined literal, get the + /// \brief If this is not a raw user-defined literal, get the /// underlying cooked literal (representing the literal with the suffix /// removed). Expr *getCookedLiteral(); @@ -402,12 +405,13 @@ public: SourceLocation getLocEnd() const { return getRParenLoc(); } - /// getUDSuffixLoc - Returns the location of a ud-suffix in the expression. + /// \brief Returns the location of a ud-suffix in the expression. + /// /// For a string literal, there may be multiple identical suffixes. This /// returns the first. SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; } - /// getUDSuffix - Returns the ud-suffix specified for this literal. + /// \brief Returns the ud-suffix specified for this literal. const IdentifierInfo *getUDSuffix() const; static bool classof(const Stmt *S) { @@ -418,7 +422,7 @@ public: friend class ASTStmtWriter; }; -/// CXXBoolLiteralExpr - [C++ 2.13.5] C++ Boolean Literal. +/// \brief A boolean literal, per ([C++ lex.bool] Boolean literals). /// class CXXBoolLiteralExpr : public Expr { bool Value; @@ -449,7 +453,9 @@ public: child_range children() { return child_range(); } }; -/// CXXNullPtrLiteralExpr - [C++0x 2.14.7] C++ Pointer Literal +/// \brief The null pointer literal (C++11 [lex.nullptr]) +/// +/// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr. class CXXNullPtrLiteralExpr : public Expr { SourceLocation Loc; public: @@ -474,11 +480,50 @@ public: child_range children() { return child_range(); } }; -/// CXXTypeidExpr - A C++ @c typeid expression (C++ [expr.typeid]), which gets -/// the type_info that corresponds to the supplied type, or the (possibly +/// \brief Implicit construction of a std::initializer_list<T> object from an +/// array temporary within list-initialization (C++11 [dcl.init.list]p5). +class CXXStdInitializerListExpr : public Expr { + Stmt *SubExpr; + + CXXStdInitializerListExpr(EmptyShell Empty) + : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(0) {} + +public: + CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr) + : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary, + Ty->isDependentType(), SubExpr->isValueDependent(), + SubExpr->isInstantiationDependent(), + SubExpr->containsUnexpandedParameterPack()), + SubExpr(SubExpr) {} + + Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); } + const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); } + + SourceLocation getLocStart() const LLVM_READONLY { + return SubExpr->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return SubExpr->getLocEnd(); + } + SourceRange getSourceRange() const LLVM_READONLY { + return SubExpr->getSourceRange(); + } + + static bool classof(const Stmt *S) { + return S->getStmtClass() == CXXStdInitializerListExprClass; + } + + child_range children() { return child_range(&SubExpr, &SubExpr + 1); } + + friend class ASTReader; + friend class ASTStmtReader; +}; + +/// A C++ \c typeid expression (C++ [expr.typeid]), which gets +/// the \c type_info that corresponds to the supplied type, or the (possibly /// dynamic) type of the supplied expression. /// -/// This represents code like @c typeid(int) or @c typeid(*objPtr) +/// This represents code like \c typeid(int) or \c typeid(*objPtr) class CXXTypeidExpr : public Expr { private: llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; @@ -521,7 +566,7 @@ public: /// \brief Retrieves the type operand of this typeid() expression after /// various required adjustments (removing reference types, cv-qualifiers). - QualType getTypeOperand() const; + QualType getTypeOperand(ASTContext &Context) const; /// \brief Retrieve source information for the type operand. TypeSourceInfo *getTypeOperandSourceInfo() const { @@ -561,10 +606,11 @@ public: } }; -/// A member reference to an MSPropertyDecl. This expression always -/// has pseudo-object type, and therefore it is typically not -/// encountered in a fully-typechecked expression except within the -/// syntactic form of a PseudoObjectExpr. +/// \brief A member reference to an MSPropertyDecl. +/// +/// This expression always has pseudo-object type, and therefore it is +/// typically not encountered in a fully-typechecked expression except +/// within the syntactic form of a PseudoObjectExpr. class MSPropertyRefExpr : public Expr { Expr *BaseExpr; MSPropertyDecl *TheDecl; @@ -619,7 +665,7 @@ public: friend class ASTStmtReader; }; -/// CXXUuidofExpr - A microsoft C++ @c __uuidof expression, which gets +/// A Microsoft C++ @c __uuidof expression, which gets /// the _GUID that corresponds to the supplied type or expression. /// /// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr) @@ -655,7 +701,7 @@ public: /// \brief Retrieves the type operand of this __uuidof() expression after /// various required adjustments (removing reference types, cv-qualifiers). - QualType getTypeOperand() const; + QualType getTypeOperand(ASTContext &Context) const; /// \brief Retrieve source information for the type operand. TypeSourceInfo *getTypeOperandSourceInfo() const { @@ -678,6 +724,8 @@ public: Operand = E; } + StringRef getUuidAsStringRef(ASTContext &Context) const; + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } @@ -687,8 +735,10 @@ public: return T->getStmtClass() == CXXUuidofExprClass; } - /// Grabs __declspec(uuid()) off a type, or returns 0 if there is none. - static UuidAttr *GetUuidAttrOfType(QualType QT); + /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to + /// a single GUID. + static UuidAttr *GetUuidAttrOfType(QualType QT, + bool *HasMultipleGUIDsPtr = 0); // Iterators child_range children() { @@ -698,17 +748,18 @@ public: } }; -/// CXXThisExpr - Represents the "this" expression in C++, which is a -/// pointer to the object on which the current member function is +/// \brief Represents the \c this expression in C++. +/// +/// This is a pointer to the object on which the current member function is /// executing (C++ [expr.prim]p3). Example: /// -/// @code +/// \code /// class Foo { /// public: /// void bar(); /// void test() { this->bar(); } /// }; -/// @endcode +/// \endcode class CXXThisExpr : public Expr { SourceLocation Loc; bool Implicit : 1; @@ -742,10 +793,11 @@ public: child_range children() { return child_range(); } }; -/// CXXThrowExpr - [C++ 15] C++ Throw Expression. This handles -/// 'throw' and 'throw' assignment-expression. When -/// assignment-expression isn't present, Op will be null. +/// \brief A C++ throw-expression (C++ [except.throw]). /// +/// This handles 'throw' (for re-throwing the current exception) and +/// 'throw' assignment-expression. When assignment-expression isn't +/// present, Op will be null. class CXXThrowExpr : public Expr { Stmt *Op; SourceLocation ThrowLoc; @@ -755,8 +807,8 @@ class CXXThrowExpr : public Expr { friend class ASTStmtReader; public: - // Ty is the void type which is used as the result type of the - // exepression. The l is the location of the throw keyword. expr + // \p Ty is the void type which is used as the result type of the + // expression. The \p l is the location of the throw keyword. \p expr // can by null, if the optional expression to throw isn't present. CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l, bool IsThrownVariableInScope) : @@ -795,10 +847,11 @@ public: } }; -/// CXXDefaultArgExpr - C++ [dcl.fct.default]. This wraps up a -/// function call argument that was created from the corresponding -/// parameter's default argument, when the call did not explicitly -/// supply arguments for all of the parameters. +/// \brief A default argument (C++ [dcl.fct.default]). +/// +/// This wraps up a function call argument that was created from the +/// corresponding parameter's default argument, when the call did not +/// explicitly supply arguments for all of the parameters. class CXXDefaultArgExpr : public Expr { /// \brief The parameter whose default is being used. /// @@ -831,20 +884,17 @@ class CXXDefaultArgExpr : public Expr { public: CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {} - - // Param is the parameter whose default argument is used by this + // \p Param is the parameter whose default argument is used by this // expression. - static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc, + static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc, ParmVarDecl *Param) { return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param); } - // Param is the parameter whose default argument is used by this - // expression, and SubExpr is the expression that will actually be used. - static CXXDefaultArgExpr *Create(ASTContext &C, - SourceLocation Loc, - ParmVarDecl *Param, - Expr *SubExpr); + // \p Param is the parameter whose default argument is used by this + // expression, and \p SubExpr is the expression that will actually be used. + static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc, + ParmVarDecl *Param, Expr *SubExpr); // Retrieve the parameter that the argument was created from. const ParmVarDecl *getParam() const { return Param.getPointer(); } @@ -866,8 +916,8 @@ public: /// used. SourceLocation getUsedLocation() const { return Loc; } - // Default argument expressions have no representation in the - // source, so they have an empty source range. + /// Default argument expressions have no representation in the + /// source, so they have an empty source range. SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); } SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } @@ -884,7 +934,10 @@ public: friend class ASTStmtWriter; }; -/// \brief This wraps a use of a C++ default initializer (technically, +/// \brief A use of a default initializer in a constructor or in aggregate +/// initialization. +/// +/// This wraps a use of a C++ default initializer (technically, /// a brace-or-equal-initializer for a non-static data member) when it /// is implicitly used in a mem-initializer-list in a constructor /// (C++11 [class.base.init]p8) or in aggregate initialization @@ -896,24 +949,24 @@ class CXXDefaultInitExpr : public Expr { /// \brief The location where the default initializer expression was used. SourceLocation Loc; - CXXDefaultInitExpr(ASTContext &C, SourceLocation Loc, FieldDecl *Field, + CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field, QualType T); CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {} public: - // Field is the non-static data member whose default initializer is used - // by this expression. - static CXXDefaultInitExpr *Create(ASTContext &C, SourceLocation Loc, + /// \p Field is the non-static data member whose default initializer is used + /// by this expression. + static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc, FieldDecl *Field) { return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType()); } - // Get the field whose initializer will be used. + /// \brief Get the field whose initializer will be used. FieldDecl *getField() { return Field; } const FieldDecl *getField() const { return Field; } - // Get the initialization expression that will be used. + /// \brief Get the initialization expression that will be used. const Expr *getExpr() const { return Field->getInClassInitializer(); } Expr *getExpr() { return Field->getInClassInitializer(); } @@ -931,16 +984,16 @@ public: friend class ASTStmtReader; }; -/// CXXTemporary - Represents a C++ temporary. +/// \brief Represents a C++ temporary. class CXXTemporary { - /// Destructor - The destructor that needs to be called. + /// \brief The destructor that needs to be called. const CXXDestructorDecl *Destructor; - CXXTemporary(const CXXDestructorDecl *destructor) + explicit CXXTemporary(const CXXDestructorDecl *destructor) : Destructor(destructor) { } public: - static CXXTemporary *Create(ASTContext &C, + static CXXTemporary *Create(const ASTContext &C, const CXXDestructorDecl *Destructor); const CXXDestructorDecl *getDestructor() const { return Destructor; } @@ -980,7 +1033,7 @@ public: CXXBindTemporaryExpr(EmptyShell Empty) : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {} - static CXXBindTemporaryExpr *Create(ASTContext &C, CXXTemporary *Temp, + static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp, Expr* SubExpr); CXXTemporary *getTemporary() { return Temp; } @@ -1019,7 +1072,7 @@ private: CXXConstructorDecl *Constructor; SourceLocation Loc; - SourceRange ParenRange; + SourceRange ParenOrBraceRange; unsigned NumArgs : 16; bool Elidable : 1; bool HadMultipleCandidates : 1; @@ -1029,7 +1082,7 @@ private: Stmt **Args; protected: - CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, + CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T, SourceLocation Loc, CXXConstructorDecl *d, bool elidable, ArrayRef<Expr *> Args, @@ -1037,7 +1090,7 @@ protected: bool ListInitialization, bool ZeroInitialization, ConstructionKind ConstructKind, - SourceRange ParenRange); + SourceRange ParenOrBraceRange); /// \brief Construct an empty C++ construction expression. CXXConstructExpr(StmtClass SC, EmptyShell Empty) @@ -1055,7 +1108,7 @@ public: ConstructKind(0), Args(0) { } - static CXXConstructExpr *Create(ASTContext &C, QualType T, + static CXXConstructExpr *Create(const ASTContext &C, QualType T, SourceLocation Loc, CXXConstructorDecl *D, bool Elidable, ArrayRef<Expr *> Args, @@ -1063,7 +1116,7 @@ public: bool ListInitialization, bool ZeroInitialization, ConstructionKind ConstructKind, - SourceRange ParenRange); + SourceRange ParenOrBraceRange); CXXConstructorDecl* getConstructor() const { return Constructor; } void setConstructor(CXXConstructorDecl *C) { Constructor = C; } @@ -1091,7 +1144,7 @@ public: ZeroInitialization = ZeroInit; } - /// \brief Determines whether this constructor is actually constructing + /// \brief Determine whether this constructor is actually constructing /// a base class (rather than a complete object). ConstructionKind getConstructionKind() const { return (ConstructionKind)ConstructKind; @@ -1111,7 +1164,7 @@ public: Expr **getArgs() const { return reinterpret_cast<Expr **>(Args); } unsigned getNumArgs() const { return NumArgs; } - /// getArg - Return the specified argument. + /// \brief Return the specified argument. Expr *getArg(unsigned Arg) { assert(Arg < NumArgs && "Arg access out of range!"); return cast<Expr>(Args[Arg]); @@ -1121,7 +1174,7 @@ public: return cast<Expr>(Args[Arg]); } - /// setArg - Set the specified argument. + /// \brief Set the specified argument. void setArg(unsigned Arg, Expr *ArgExpr) { assert(Arg < NumArgs && "Arg access out of range!"); Args[Arg] = ArgExpr; @@ -1129,8 +1182,8 @@ public: SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; - SourceRange getParenRange() const { return ParenRange; } - void setParenRange(SourceRange Range) { ParenRange = Range; } + SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; } + void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstructExprClass || @@ -1149,43 +1202,42 @@ public: /// notation (C++ [expr.type.conv]). /// /// Example: -/// @code +/// \code /// x = int(0.5); -/// @endcode +/// \endcode class CXXFunctionalCastExpr : public ExplicitCastExpr { - SourceLocation TyBeginLoc; + SourceLocation LParenLoc; SourceLocation RParenLoc; CXXFunctionalCastExpr(QualType ty, ExprValueKind VK, TypeSourceInfo *writtenTy, - SourceLocation tyBeginLoc, CastKind kind, - Expr *castExpr, unsigned pathSize, - SourceLocation rParenLoc) + CastKind kind, Expr *castExpr, unsigned pathSize, + SourceLocation lParenLoc, SourceLocation rParenLoc) : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, castExpr, pathSize, writtenTy), - TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {} + LParenLoc(lParenLoc), RParenLoc(rParenLoc) {} explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize) : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { } public: - static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T, + static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, TypeSourceInfo *Written, - SourceLocation TyBeginLoc, CastKind Kind, Expr *Op, const CXXCastPath *Path, + SourceLocation LPLoc, SourceLocation RPLoc); - static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context, + static CXXFunctionalCastExpr *CreateEmpty(const ASTContext &Context, unsigned PathSize); - SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } - void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; } + SourceLocation getLParenLoc() const { return LParenLoc; } + void setLParenLoc(SourceLocation L) { LParenLoc = L; } SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceLocation getLocStart() const LLVM_READONLY { return TyBeginLoc; } - SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY; static bool classof(const Stmt *T) { return T->getStmtClass() == CXXFunctionalCastExprClass; @@ -1200,21 +1252,21 @@ public: /// constructor to build a temporary object. With N == 1 arguments the /// functional cast expression will be represented by CXXFunctionalCastExpr. /// Example: -/// @code +/// \code /// struct X { X(int, float); } /// /// X create_X() { /// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr /// }; -/// @endcode +/// \endcode class CXXTemporaryObjectExpr : public CXXConstructExpr { TypeSourceInfo *Type; public: - CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons, + CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons, TypeSourceInfo *Type, ArrayRef<Expr *> Args, - SourceRange parenRange, + SourceRange ParenOrBraceRange, bool HadMultipleCandidates, bool ListInitialization, bool ZeroInitialization); @@ -1244,26 +1296,35 @@ public: /// } /// \endcode /// -/// Lambda expressions can capture local variables, either by copying +/// C++11 lambda expressions can capture local variables, either by copying /// the values of those local variables at the time the function /// object is constructed (not when it is called!) or by holding a /// reference to the local variable. These captures can occur either /// implicitly or can be written explicitly between the square /// brackets ([...]) that start the lambda expression. +/// +/// C++1y introduces a new form of "capture" called an init-capture that +/// includes an initializing expression (rather than capturing a variable), +/// and which can never occur implicitly. class LambdaExpr : public Expr { enum { /// \brief Flag used by the Capture class to indicate that the given /// capture was implicit. Capture_Implicit = 0x01, - /// \brief Flag used by the Capture class to indciate that the + /// \brief Flag used by the Capture class to indicate that the /// given capture was by-copy. + /// + /// This includes the case of a non-reference init-capture. Capture_ByCopy = 0x02 }; /// \brief The source range that covers the lambda introducer ([...]). SourceRange IntroducerRange; + /// \brief The source location of this lambda's capture-default ('=' or '&'). + SourceLocation CaptureDefaultLoc; + /// \brief The number of captures. unsigned NumCaptures : 16; @@ -1297,9 +1358,10 @@ class LambdaExpr : public Expr { // array captures. public: - /// \brief Describes the capture of either a variable or 'this'. + /// \brief Describes the capture of a variable or of \c this, or of a + /// C++1y init-capture. class Capture { - llvm::PointerIntPair<VarDecl *, 2> VarAndBits; + llvm::PointerIntPair<Decl *, 2> DeclAndBits; SourceLocation Loc; SourceLocation EllipsisLoc; @@ -1307,15 +1369,17 @@ public: friend class ASTStmtWriter; public: - /// \brief Create a new capture. + /// \brief Create a new capture of a variable or of \c this. /// /// \param Loc The source location associated with this capture. /// - /// \param Kind The kind of capture (this, byref, bycopy). + /// \param Kind The kind of capture (this, byref, bycopy), which must + /// not be init-capture. /// /// \param Implicit Whether the capture was implicit or explicit. /// - /// \param Var The local variable being captured, or null if capturing this. + /// \param Var The local variable being captured, or null if capturing + /// \c this. /// /// \param EllipsisLoc The location of the ellipsis (...) for a /// capture that is a pack expansion, or an invalid source @@ -1327,36 +1391,43 @@ public: /// \brief Determine the kind of capture. LambdaCaptureKind getCaptureKind() const; - /// \brief Determine whether this capture handles the C++ 'this' + /// \brief Determine whether this capture handles the C++ \c this /// pointer. - bool capturesThis() const { return VarAndBits.getPointer() == 0; } + bool capturesThis() const { return DeclAndBits.getPointer() == 0; } /// \brief Determine whether this capture handles a variable. - bool capturesVariable() const { return VarAndBits.getPointer() != 0; } + bool capturesVariable() const { + return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer()); + } + + /// \brief Determine whether this is an init-capture. + bool isInitCapture() const { + return capturesVariable() && getCapturedVar()->isInitCapture(); + } /// \brief Retrieve the declaration of the local variable being /// captured. /// - /// This operation is only valid if this capture does not capture - /// 'this'. - VarDecl *getCapturedVar() const { - assert(!capturesThis() && "No variable available for 'this' capture"); - return VarAndBits.getPointer(); + /// This operation is only valid if this capture is a variable capture + /// (other than a capture of \c this). + VarDecl *getCapturedVar() const { + assert(capturesVariable() && "No variable available for 'this' capture"); + return cast<VarDecl>(DeclAndBits.getPointer()); } /// \brief Determine whether this was an implicit capture (not /// written between the square brackets introducing the lambda). - bool isImplicit() const { return VarAndBits.getInt() & Capture_Implicit; } + bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; } - /// \brief Determine whether this was an explicit capture, written - /// between the square brackets introducing the lambda. + /// \brief Determine whether this was an explicit capture (written + /// between the square brackets introducing the lambda). bool isExplicit() const { return !isImplicit(); } /// \brief Retrieve the source location of the capture. /// /// For an explicit capture, this returns the location of the /// explicit capture in the source. For an implicit capture, this - /// returns the location at which the variable or 'this' was first + /// returns the location at which the variable or \c this was first /// used. SourceLocation getLocation() const { return Loc; } @@ -1376,6 +1447,7 @@ private: /// \brief Construct a lambda expression. LambdaExpr(QualType T, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, + SourceLocation CaptureDefaultLoc, ArrayRef<Capture> Captures, bool ExplicitParams, bool ExplicitResultType, @@ -1414,10 +1486,11 @@ private: public: /// \brief Construct a new lambda expression. - static LambdaExpr *Create(ASTContext &C, + static LambdaExpr *Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, + SourceLocation CaptureDefaultLoc, ArrayRef<Capture> Captures, bool ExplicitParams, bool ExplicitResultType, @@ -1429,14 +1502,20 @@ public: /// \brief Construct a new lambda expression that will be deserialized from /// an external source. - static LambdaExpr *CreateDeserialized(ASTContext &C, unsigned NumCaptures, + static LambdaExpr *CreateDeserialized(const ASTContext &C, + unsigned NumCaptures, unsigned NumArrayIndexVars); - + /// \brief Determine the default capture kind for this lambda. LambdaCaptureDefault getCaptureDefault() const { return static_cast<LambdaCaptureDefault>(CaptureDefault); } + /// \brief Retrieve the location of this lambda's capture-default, if any. + SourceLocation getCaptureDefaultLoc() const { + return CaptureDefaultLoc; + } + /// \brief An iterator that walks over the captures of the lambda, /// both implicit and explicit. typedef const Capture *capture_iterator; @@ -1495,15 +1574,24 @@ public: /// brackets ([...]). SourceRange getIntroducerRange() const { return IntroducerRange; } - /// \brief Retrieve the class that corresponds to the lambda, which - /// stores the captures in its fields and provides the various - /// operations permitted on a lambda (copying, calling). + /// \brief Retrieve the class that corresponds to the lambda. + /// + /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the + /// captures in its fields and provides the various operations permitted + /// on a lambda (copying, calling). CXXRecordDecl *getLambdaClass() const; /// \brief Retrieve the function call operator associated with this /// lambda expression. CXXMethodDecl *getCallOperator() const; + /// \brief If this is a generic lambda expression, retrieve the template + /// parameter list associated with it, or else return null. + TemplateParameterList *getTemplateParameterList() const; + + /// \brief Whether this is a generic lambda. + bool isGenericLambda() const { return getTemplateParameterList(); } + /// \brief Retrieve the body of the lambda. CompoundStmt *getBody() const; @@ -1535,10 +1623,8 @@ public: friend class ASTStmtWriter; }; -/// CXXScalarValueInitExpr - [C++ 5.2.3p2] -/// Expression "T()" which creates a value-initialized rvalue of type -/// T, which is a non-class type. -/// +/// An expression "T()" which creates a value-initialized rvalue of type +/// T, which is a non-class type. See (C++98 [5.2.3p2]). class CXXScalarValueInitExpr : public Expr { SourceLocation RParenLoc; TypeSourceInfo *TypeInfo; @@ -1575,11 +1661,11 @@ public: child_range children() { return child_range(); } }; -/// @brief Represents a new-expression for memory allocation and constructor -// calls, e.g: "new CXXNewExpr(foo)". +/// \brief Represents a new-expression for memory allocation and constructor +/// calls, e.g: "new CXXNewExpr(foo)". class CXXNewExpr : public Expr { - // Contains an optional array size expression, an optional initialization - // expression, and any number of optional placement arguments, in that order. + /// Contains an optional array size expression, an optional initialization + /// expression, and any number of optional placement arguments, in that order. Stmt **SubExprs; /// \brief Points to the allocation function used. FunctionDecl *OperatorNew; @@ -1600,18 +1686,18 @@ class CXXNewExpr : public Expr { /// \brief Source-range of a paren-delimited initializer. SourceRange DirectInitRange; - // Was the usage ::new, i.e. is the global new to be used? + /// Was the usage ::new, i.e. is the global new to be used? bool GlobalNew : 1; - // Do we allocate an array? If so, the first SubExpr is the size expression. + /// Do we allocate an array? If so, the first SubExpr is the size expression. bool Array : 1; - // If this is an array allocation, does the usual deallocation - // function for the allocated type want to know the allocated size? + /// If this is an array allocation, does the usual deallocation + /// function for the allocated type want to know the allocated size? bool UsualArrayDeleteWantsSize : 1; - // The number of placement new arguments. + /// The number of placement new arguments. unsigned NumPlacementArgs : 13; - // What kind of initializer do we have? Could be none, parens, or braces. - // In storage, we distinguish between "none, and no initializer expr", and - // "none, but an implicit initializer expr". + /// What kind of initializer do we have? Could be none, parens, or braces. + /// In storage, we distinguish between "none, and no initializer expr", and + /// "none, but an implicit initializer expr". unsigned StoredInitializationStyle : 2; friend class ASTStmtReader; @@ -1623,7 +1709,7 @@ public: ListInit ///< New-expression has a C++11 list-initializer. }; - CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, + CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew, FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize, ArrayRef<Expr*> placementArgs, SourceRange typeIdParens, Expr *arraySize, @@ -1633,8 +1719,8 @@ public: explicit CXXNewExpr(EmptyShell Shell) : Expr(CXXNewExprClass, Shell), SubExprs(0) { } - void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs, - bool hasInitializer); + void AllocateArgsArray(const ASTContext &C, bool isArray, + unsigned numPlaceArgs, bool hasInitializer); QualType getAllocatedType() const { assert(getType()->isPointerType()); @@ -1646,15 +1732,17 @@ public: } /// \brief True if the allocation result needs to be null-checked. - /// C++0x [expr.new]p13: + /// + /// C++11 [expr.new]p13: /// If the allocation function returns null, initialization shall /// not be done, the deallocation function shall not be called, /// and the value of the new-expression shall be null. + /// /// An allocation function is not allowed to return null unless it /// has a non-throwing exception-specification. The '03 rule is /// identical except that the definition of a non-throwing /// exception specification is just "is it throw()?". - bool shouldNullCheckAllocation(ASTContext &Ctx) const; + bool shouldNullCheckAllocation(const ASTContext &Ctx) const; FunctionDecl *getOperatorNew() const { return OperatorNew; } void setOperatorNew(FunctionDecl *D) { OperatorNew = D; } @@ -1706,7 +1794,7 @@ public: return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0; } - /// \brief Returns the CXXConstructExpr from this new-expression, or NULL. + /// \brief Returns the CXXConstructExpr from this new-expression, or null. const CXXConstructExpr* getConstructExpr() const { return dyn_cast_or_null<CXXConstructExpr>(getInitializer()); } @@ -1768,22 +1856,22 @@ public: /// \brief Represents a \c delete expression for memory deallocation and /// destructor calls, e.g. "delete[] pArray". class CXXDeleteExpr : public Expr { - // Points to the operator delete overload that is used. Could be a member. + /// Points to the operator delete overload that is used. Could be a member. FunctionDecl *OperatorDelete; - // The pointer expression to be deleted. + /// The pointer expression to be deleted. Stmt *Argument; - // Location of the expression. + /// Location of the expression. SourceLocation Loc; - // Is this a forced global delete, i.e. "::delete"? + /// Is this a forced global delete, i.e. "::delete"? bool GlobalDelete : 1; - // Is this the array form of delete, i.e. "delete[]"? + /// Is this the array form of delete, i.e. "delete[]"? bool ArrayForm : 1; - // ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied - // to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm - // will be true). + /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied + /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm + /// will be true). bool ArrayFormAsWritten : 1; - // Does the usual deallocation function for the element type require - // a size_t argument? + /// Does the usual deallocation function for the element type require + /// a size_t argument? bool UsualArrayDeleteWantsSize : 1; public: CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm, @@ -1816,9 +1904,10 @@ public: Expr *getArgument() { return cast<Expr>(Argument); } const Expr *getArgument() const { return cast<Expr>(Argument); } - /// \brief Retrieve the type being destroyed. If the type being - /// destroyed is a dependent type which may or may not be a pointer, - /// return an invalid type. + /// \brief Retrieve the type being destroyed. + /// + /// If the type being destroyed is a dependent type which may or may not + /// be a pointer, return an invalid type. QualType getDestroyedType() const; SourceLocation getLocStart() const LLVM_READONLY { return Loc; } @@ -1918,7 +2007,7 @@ class CXXPseudoDestructorExpr : public Expr { friend class ASTStmtReader; public: - CXXPseudoDestructorExpr(ASTContext &Context, + CXXPseudoDestructorExpr(const ASTContext &Context, Expr *Base, bool isArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, TypeSourceInfo *ScopeType, @@ -1935,7 +2024,7 @@ public: /// \brief Determines whether this member expression actually had /// a C++ nested-name-specifier prior to the name of the member, e.g., /// x->Base::foo. - bool hasQualifier() const { return QualifierLoc; } + bool hasQualifier() const { return QualifierLoc.hasQualifier(); } /// \brief Retrieves the nested-name-specifier that qualifies the type name, /// with source-location information. @@ -1943,7 +2032,7 @@ public: /// \brief If the member name was qualified, retrieves the /// nested-name-specifier that precedes the member name. Otherwise, returns - /// NULL. + /// null. NestedNameSpecifier *getQualifier() const { return QualifierLoc.getNestedNameSpecifier(); } @@ -1978,7 +2067,7 @@ public: /// /// This type-source information is available for non-dependent /// pseudo-destructor expressions and some dependent pseudo-destructor - /// expressions. Returns NULL if we only have the identifier for a + /// expressions. Returns null if we only have the identifier for a /// dependent pseudo-destructor expression. TypeSourceInfo *getDestroyedTypeInfo() const { return DestroyedType.getTypeSourceInfo(); @@ -2025,23 +2114,23 @@ public: /// implementation of TR1/C++11 type trait templates. /// /// Example: -/// @code +/// \code /// __is_pod(int) == true /// __is_enum(std::string) == false -/// @endcode +/// \endcode class UnaryTypeTraitExpr : public Expr { - /// UTT - The trait. A UnaryTypeTrait enum in MSVC compat unsigned. + /// \brief The trait. A UnaryTypeTrait enum in MSVC compatible unsigned. unsigned UTT : 31; /// The value of the type trait. Unspecified if dependent. bool Value : 1; - /// Loc - The location of the type trait keyword. + /// \brief The location of the type trait keyword. SourceLocation Loc; - /// RParen - The location of the closing paren. + /// \brief The location of the closing paren. SourceLocation RParen; - /// The type being queried. + /// \brief The type being queried. TypeSourceInfo *QueriedType; public: @@ -2083,26 +2172,26 @@ public: /// implementation of TR1/C++11 type trait templates. /// /// Example: -/// @code +/// \code /// __is_base_of(Base, Derived) == true -/// @endcode +/// \endcode class BinaryTypeTraitExpr : public Expr { - /// BTT - The trait. A BinaryTypeTrait enum in MSVC compat unsigned. + /// \brief The trait. A BinaryTypeTrait enum in MSVC compatible unsigned. unsigned BTT : 8; /// The value of the type trait. Unspecified if dependent. bool Value : 1; - /// Loc - The location of the type trait keyword. + /// \brief The location of the type trait keyword. SourceLocation Loc; - /// RParen - The location of the closing paren. + /// \brief The location of the closing paren. SourceLocation RParen; - /// The lhs type being queried. + /// \brief The lhs type being queried. TypeSourceInfo *LhsType; - /// The rhs type being queried. + /// \brief The rhs type being queried. TypeSourceInfo *RhsType; public: @@ -2184,13 +2273,14 @@ class TypeTraitExpr : public Expr { public: /// \brief Create a new type trait expression. - static TypeTraitExpr *Create(ASTContext &C, QualType T, SourceLocation Loc, - TypeTrait Kind, + static TypeTraitExpr *Create(const ASTContext &C, QualType T, + SourceLocation Loc, TypeTrait Kind, ArrayRef<TypeSourceInfo *> Args, SourceLocation RParenLoc, bool Value); - static TypeTraitExpr *CreateDeserialized(ASTContext &C, unsigned NumArgs); + static TypeTraitExpr *CreateDeserialized(const ASTContext &C, + unsigned NumArgs); /// \brief Determine which type trait this expression uses. TypeTrait getTrait() const { @@ -2249,10 +2339,10 @@ public: /// __array_rank and __array_extent. /// /// Example: -/// @code +/// \code /// __array_rank(int[10][20]) == 2 /// __array_extent(int, 1) == 20 -/// @endcode +/// \endcode class ArrayTypeTraitExpr : public Expr { virtual void anchor(); @@ -2319,12 +2409,12 @@ public: /// \brief An expression trait intrinsic. /// /// Example: -/// @code +/// \code /// __is_lvalue_expr(std::cout) == true /// __is_lvalue_expr(1) == false -/// @endcode +/// \endcode class ExpressionTraitExpr : public Expr { - /// \brief The trait. A ExpressionTrait enum in MSVC compat unsigned. + /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned. unsigned ET : 31; /// \brief The value of the type trait. Unspecified if dependent. bool Value : 1; @@ -2403,7 +2493,7 @@ protected: return const_cast<OverloadExpr*>(this)->getTemplateKWAndArgsInfo(); } - OverloadExpr(StmtClass K, ASTContext &C, + OverloadExpr(StmtClass K, const ASTContext &C, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, @@ -2417,7 +2507,7 @@ protected: : Expr(K, Empty), QualifierLoc(), Results(0), NumResults(0), HasTemplateKWAndArgsInfo(false) { } - void initializeResults(ASTContext &C, + void initializeResults(const ASTContext &C, UnresolvedSetIterator Begin, UnresolvedSetIterator End); @@ -2428,7 +2518,7 @@ public: bool HasFormOfMemberPointer; }; - /// Finds the overloaded expression in the given expression of + /// \brief Finds the overloaded expression in the given expression \p E of /// OverloadTy. /// /// \return the expression (which must be there) and true if it has @@ -2561,10 +2651,11 @@ public: /// parsing but could not resolve to a specific declaration. /// /// This arises in several ways: -/// * we might be waiting for argument-dependent lookup -/// * the name might resolve to an overloaded function +/// * we might be waiting for argument-dependent lookup; +/// * the name might resolve to an overloaded function; /// and eventually: -/// * the lookup might have included a function template +/// * the lookup might have included a function template. +/// /// These never include UnresolvedUsingValueDecls, which are always class /// members and therefore appear only in UnresolvedMemberLookupExprs. class UnresolvedLookupExpr : public OverloadExpr { @@ -2584,7 +2675,7 @@ class UnresolvedLookupExpr : public OverloadExpr { /// against the qualified-lookup bits. CXXRecordDecl *NamingClass; - UnresolvedLookupExpr(ASTContext &C, + UnresolvedLookupExpr(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, @@ -2606,7 +2697,7 @@ class UnresolvedLookupExpr : public OverloadExpr { friend class ASTStmtReader; public: - static UnresolvedLookupExpr *Create(ASTContext &C, + static UnresolvedLookupExpr *Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, @@ -2618,7 +2709,7 @@ public: ADL, Overloaded, 0, Begin, End); } - static UnresolvedLookupExpr *Create(ASTContext &C, + static UnresolvedLookupExpr *Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, @@ -2628,7 +2719,7 @@ public: UnresolvedSetIterator Begin, UnresolvedSetIterator End); - static UnresolvedLookupExpr *CreateEmpty(ASTContext &C, + static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); @@ -2671,7 +2762,7 @@ public: /// DependentScopeDeclRefExpr node is used only within C++ templates when /// the qualification (e.g., X<T>::) refers to a dependent type. In /// this case, X<T>::value cannot resolve to a declaration because the -/// declaration will differ from on instantiation of X<T> to the +/// declaration will differ from one instantiation of X<T> to the /// next. Therefore, DependentScopeDeclRefExpr keeps track of the /// qualifier (X<T>::) and the name of the entity being referenced /// ("value"). Such expressions will instantiate to a DeclRefExpr once the @@ -2681,7 +2772,7 @@ class DependentScopeDeclRefExpr : public Expr { /// declaration name. NestedNameSpecifierLoc QualifierLoc; - /// The name of the entity we will be referencing. + /// \brief The name of the entity we will be referencing. DeclarationNameInfo NameInfo; /// \brief Whether the name includes info for explicit template @@ -2706,13 +2797,13 @@ class DependentScopeDeclRefExpr : public Expr { const TemplateArgumentListInfo *Args); public: - static DependentScopeDeclRefExpr *Create(ASTContext &C, + static DependentScopeDeclRefExpr *Create(const ASTContext &C, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs); - static DependentScopeDeclRefExpr *CreateEmpty(ASTContext &C, + static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); @@ -2723,13 +2814,14 @@ public: DeclarationName getDeclName() const { return NameInfo.getName(); } /// \brief Retrieve the location of the name within the expression. + /// + /// For example, in "X<T>::value" this is the location of "value". SourceLocation getLocation() const { return NameInfo.getLoc(); } /// \brief Retrieve the nested-name-specifier that qualifies the /// name, with source location information. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } - /// \brief Retrieve the nested-name-specifier that qualifies this /// declaration. NestedNameSpecifier *getQualifier() const { @@ -2779,6 +2871,7 @@ public: } /// \brief Retrieves the optional explicit template arguments. + /// /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { @@ -2800,6 +2893,8 @@ public: return getExplicitTemplateArgs().NumTemplateArgs; } + /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr, + /// and differs from getLocation().getStart(). SourceLocation getLocStart() const LLVM_READONLY { return QualifierLoc.getBeginLoc(); } @@ -2819,7 +2914,7 @@ public: friend class ASTStmtWriter; }; -/// Represents an expression --- generally a full-expression --- which +/// Represents an expression -- generally a full-expression -- that /// introduces cleanups to be run at the end of the sub-expression's /// evaluation. The most common source of expression-introduced /// cleanups is temporary objects in C++, but several other kinds of @@ -2852,10 +2947,10 @@ private: friend class ASTStmtReader; public: - static ExprWithCleanups *Create(ASTContext &C, EmptyShell empty, + static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty, unsigned numObjects); - static ExprWithCleanups *Create(ASTContext &C, Expr *subexpr, + static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr, ArrayRef<CleanupObject> objects); ArrayRef<CleanupObject> getObjects() const { @@ -2872,7 +2967,7 @@ public: Expr *getSubExpr() { return cast<Expr>(SubExpr); } const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } - /// setSubExpr - As with any mutator of the AST, be very careful + /// As with any mutator of the AST, be very careful /// when modifying an existing AST to preserve its invariants. void setSubExpr(Expr *E) { SubExpr = E; } @@ -2935,13 +3030,13 @@ class CXXUnresolvedConstructExpr : public Expr { friend class ASTStmtReader; public: - static CXXUnresolvedConstructExpr *Create(ASTContext &C, + static CXXUnresolvedConstructExpr *Create(const ASTContext &C, TypeSourceInfo *Type, SourceLocation LParenLoc, ArrayRef<Expr*> Args, SourceLocation RParenLoc); - static CXXUnresolvedConstructExpr *CreateEmpty(ASTContext &C, + static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C, unsigned NumArgs); /// \brief Retrieve the type that is being constructed, as specified @@ -2993,7 +3088,10 @@ public: } SourceLocation getLocStart() const LLVM_READONLY; - SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + assert(RParenLoc.isValid() || NumArgs == 1); + return RParenLoc.isValid() ? RParenLoc : getArg(0)->getLocEnd(); + } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXUnresolvedConstructExprClass; @@ -3047,6 +3145,7 @@ class CXXDependentScopeMemberExpr : public Expr { /// \brief The member to which this member expression refers, which /// can be name, overloaded operator, or destructor. + /// /// FIXME: could also be a template-id DeclarationNameInfo MemberNameInfo; @@ -3061,36 +3160,32 @@ class CXXDependentScopeMemberExpr : public Expr { ->getTemplateKWAndArgsInfo(); } - CXXDependentScopeMemberExpr(ASTContext &C, - Expr *Base, QualType BaseType, bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierFoundInScope, - DeclarationNameInfo MemberNameInfo, - const TemplateArgumentListInfo *TemplateArgs); + CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, + QualType BaseType, bool IsArrow, + SourceLocation OperatorLoc, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, + NamedDecl *FirstQualifierFoundInScope, + DeclarationNameInfo MemberNameInfo, + const TemplateArgumentListInfo *TemplateArgs); public: - CXXDependentScopeMemberExpr(ASTContext &C, - Expr *Base, QualType BaseType, - bool IsArrow, + CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, + QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo); static CXXDependentScopeMemberExpr * - Create(ASTContext &C, - Expr *Base, QualType BaseType, bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierFoundInScope, + Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, + SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs); static CXXDependentScopeMemberExpr * - CreateEmpty(ASTContext &C, bool HasTemplateKWAndArgsInfo, + CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); /// \brief True if this is an implicit access, i.e. one in which the @@ -3197,6 +3292,7 @@ public: } /// \brief Retrieves the optional explicit template arguments. + /// /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { @@ -3259,11 +3355,13 @@ public: /// produced a set of overloaded functions. /// /// The member access may be explicit or implicit: +/// \code /// struct A { /// int a, b; /// int explicitAccess() { return this->a + this->A::b; } /// int implicitAccess() { return a + A::b; } /// }; +/// \endcode /// /// In the final AST, an explicit access always becomes a MemberExpr. /// An implicit access may become either a MemberExpr or a @@ -3278,17 +3376,18 @@ class UnresolvedMemberExpr : public OverloadExpr { bool HasUnresolvedUsing : 1; /// \brief The expression for the base pointer or class reference, - /// e.g., the \c x in x.f. This can be null if this is an 'unbased' - /// member expression + /// e.g., the \c x in x.f. + /// + /// This can be null if this is an 'unbased' member expression. Stmt *Base; - /// \brief The type of the base expression; never null. + /// \brief The type of the base expression; never null. QualType BaseType; /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; - UnresolvedMemberExpr(ASTContext &C, bool HasUnresolvedUsing, + UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, @@ -3305,7 +3404,7 @@ class UnresolvedMemberExpr : public OverloadExpr { public: static UnresolvedMemberExpr * - Create(ASTContext &C, bool HasUnresolvedUsing, + Create(const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, @@ -3315,12 +3414,13 @@ public: UnresolvedSetIterator Begin, UnresolvedSetIterator End); static UnresolvedMemberExpr * - CreateEmpty(ASTContext &C, bool HasTemplateKWAndArgsInfo, + CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); - /// \brief True if this is an implicit access, i.e. one in which the - /// member being accessed was not written in the source. The source - /// location of the operator is invalid in this case. + /// \brief True if this is an implicit access, i.e., one in which the + /// member being accessed was not written in the source. + /// + /// The source location of the operator is invalid in this case. bool isImplicitAccess() const; /// \brief Retrieve the base object of this member expressions, @@ -3347,7 +3447,7 @@ public: /// \brief Retrieve the location of the '->' or '.' operator. SourceLocation getOperatorLoc() const { return OperatorLoc; } - /// \brief Retrieves the naming class of this lookup. + /// \brief Retrieve the naming class of this lookup. CXXRecordDecl *getNamingClass() const; /// \brief Retrieve the full name info for the member that this expression @@ -3362,6 +3462,10 @@ public: // expression refers to. SourceLocation getMemberLoc() const { return getNameLoc(); } + // \brief Return the preferred location (the member name) for the arrow when + // diagnosing a problem with this expression. + SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); } + SourceLocation getLocStart() const LLVM_READONLY { if (!isImplicitAccess()) return Base->getLocStart(); @@ -3386,7 +3490,7 @@ public: } }; -/// \brief Represents a C++0x noexcept expression (C++ [expr.unary.noexcept]). +/// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]). /// /// The noexcept expression tests whether a given expression might throw. Its /// result is a boolean constant. @@ -3428,7 +3532,7 @@ public: child_range children() { return child_range(&Operand, &Operand + 1); } }; -/// \brief Represents a C++0x pack expansion that produces a sequence of +/// \brief Represents a C++11 pack expansion that produces a sequence of /// expressions. /// /// A pack expansion expression contains a pattern (which itself is an @@ -3527,7 +3631,7 @@ inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() { /// }; /// \endcode class SizeOfPackExpr : public Expr { - /// \brief The location of the 'sizeof' keyword. + /// \brief The location of the \c sizeof keyword. SourceLocation OperatorLoc; /// \brief The location of the name of the parameter pack. @@ -3550,7 +3654,7 @@ class SizeOfPackExpr : public Expr { friend class ASTStmtWriter; public: - /// \brief Creates a value-dependent expression that computes the length of + /// \brief Create a value-dependent expression that computes the length of /// the given parameter pack. SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc) @@ -3561,7 +3665,7 @@ public: OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), Length(0), Pack(Pack) { } - /// \brief Creates an expression that computes the length of + /// \brief Create an expression that computes the length of /// the given parameter pack, which is already known. SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, @@ -3744,11 +3848,11 @@ class FunctionParmPackExpr : public Expr { friend class ASTStmtReader; public: - static FunctionParmPackExpr *Create(ASTContext &Context, QualType T, + static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T, ParmVarDecl *ParamPack, SourceLocation NameLoc, ArrayRef<Decl *> Params); - static FunctionParmPackExpr *CreateEmpty(ASTContext &Context, + static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context, unsigned NumParams); /// \brief Get the parameter pack which this expression refers to. @@ -3779,7 +3883,7 @@ public: child_range children() { return child_range(); } }; -/// \brief Represents a prvalue temporary that written into memory so that +/// \brief Represents a prvalue temporary that is written into memory so that /// a reference can bind to it. /// /// Prvalue expressions are materialized when they need to have an address @@ -3795,30 +3899,60 @@ public: /// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues /// (either an lvalue or an xvalue, depending on the kind of reference binding /// to it), maintaining the invariant that references always bind to glvalues. +/// +/// Reference binding and copy-elision can both extend the lifetime of a +/// temporary. When either happens, the expression will also track the +/// declaration which is responsible for the lifetime extension. class MaterializeTemporaryExpr : public Expr { +public: /// \brief The temporary-generating expression whose value will be /// materialized. Stmt *Temporary; + /// \brief The declaration which lifetime-extended this reference, if any. + /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl. + const ValueDecl *ExtendingDecl; + friend class ASTStmtReader; friend class ASTStmtWriter; public: MaterializeTemporaryExpr(QualType T, Expr *Temporary, - bool BoundToLvalueReference) + bool BoundToLvalueReference, + const ValueDecl *ExtendedBy) : Expr(MaterializeTemporaryExprClass, T, BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary, Temporary->isTypeDependent(), Temporary->isValueDependent(), Temporary->isInstantiationDependent(), Temporary->containsUnexpandedParameterPack()), - Temporary(Temporary) { } + Temporary(Temporary), ExtendingDecl(ExtendedBy) { + } MaterializeTemporaryExpr(EmptyShell Empty) : Expr(MaterializeTemporaryExprClass, Empty) { } /// \brief Retrieve the temporary-generating subexpression whose value will /// be materialized into a glvalue. - Expr *GetTemporaryExpr() const { return reinterpret_cast<Expr *>(Temporary); } + Expr *GetTemporaryExpr() const { return static_cast<Expr *>(Temporary); } + + /// \brief Retrieve the storage duration for the materialized temporary. + StorageDuration getStorageDuration() const { + if (!ExtendingDecl) + return SD_FullExpression; + // FIXME: This is not necessarily correct for a temporary materialized + // within a default initializer. + if (isa<FieldDecl>(ExtendingDecl)) + return SD_Automatic; + return cast<VarDecl>(ExtendingDecl)->getStorageDuration(); + } + + /// \brief Get the declaration which triggered the lifetime-extension of this + /// temporary, if any. + const ValueDecl *getExtendingDecl() const { return ExtendingDecl; } + + void setExtendingDecl(const ValueDecl *ExtendedBy) { + ExtendingDecl = ExtendedBy; + } /// \brief Determine whether this materialized temporary is bound to an /// lvalue reference; otherwise, it's bound to an rvalue reference. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h index a94c69a..aeb55da 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h @@ -143,12 +143,13 @@ class ObjCArrayLiteral : public Expr { : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {} public: - static ObjCArrayLiteral *Create(ASTContext &C, + static ObjCArrayLiteral *Create(const ASTContext &C, ArrayRef<Expr *> Elements, QualType T, ObjCMethodDecl * Method, SourceRange SR); - static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements); + static ObjCArrayLiteral *CreateEmpty(const ASTContext &C, + unsigned NumElements); SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } @@ -289,13 +290,13 @@ class ObjCDictionaryLiteral : public Expr { } public: - static ObjCDictionaryLiteral *Create(ASTContext &C, + static ObjCDictionaryLiteral *Create(const ASTContext &C, ArrayRef<ObjCDictionaryElement> VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *method, SourceRange SR); - static ObjCDictionaryLiteral *CreateEmpty(ASTContext &C, + static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C, unsigned NumElements, bool HasPackExpansions); @@ -807,7 +808,7 @@ public: explicit ObjCSubscriptRefExpr(EmptyShell Empty) : Expr(ObjCSubscriptRefExprClass, Empty) {} - static ObjCSubscriptRefExpr *Create(ASTContext &C, + static ObjCSubscriptRefExpr *Create(const ASTContext &C, Expr *base, Expr *key, QualType T, ObjCMethodDecl *getMethod, @@ -1003,13 +1004,13 @@ class ObjCMessageExpr : public Expr { return getNumSelectorLocs(); } - static ObjCMessageExpr *alloc(ASTContext &C, + static ObjCMessageExpr *alloc(const ASTContext &C, ArrayRef<Expr *> Args, SourceLocation RBraceLoc, ArrayRef<SourceLocation> SelLocs, Selector Sel, SelectorLocationsKind &SelLocsK); - static ObjCMessageExpr *alloc(ASTContext &C, + static ObjCMessageExpr *alloc(const ASTContext &C, unsigned NumArgs, unsigned NumStoredSelLocs); @@ -1051,7 +1052,7 @@ public: /// \param Args The message send arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. - static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, @@ -1087,7 +1088,7 @@ public: /// \param Args The message send arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. - static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, @@ -1121,7 +1122,7 @@ public: /// \param Args The message send arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. - static ObjCMessageExpr *Create(ASTContext &Context, QualType T, + static ObjCMessageExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, @@ -1139,7 +1140,7 @@ public: /// /// \param NumArgs The number of message arguments, not including /// the receiver. - static ObjCMessageExpr *CreateEmpty(ASTContext &Context, + static ObjCMessageExpr *CreateEmpty(const ASTContext &Context, unsigned NumArgs, unsigned NumStoredSelLocs); diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h index 81fcf24..b077426 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h @@ -329,7 +329,12 @@ public: /// \brief Whether this pointer is non-NULL. /// /// This operation does not require the AST node to be deserialized. - operator bool() const { return Ptr != 0; } + LLVM_EXPLICIT operator bool() const { return Ptr != 0; } + + /// \brief Whether this pointer is non-NULL. + /// + /// This operation does not require the AST node to be deserialized. + bool isValid() const { return Ptr != 0; } /// \brief Whether this pointer is currently stored as an offset. bool isOffset() const { return Ptr & 0x01; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h b/contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h index c43e44c..54c9d88 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h +++ b/contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h @@ -41,6 +41,7 @@ public: GlobalDecl(const VarDecl *D) { Init(D);} GlobalDecl(const FunctionDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); } + GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) diff --git a/contrib/llvm/tools/clang/include/clang/AST/LambdaMangleContext.h b/contrib/llvm/tools/clang/include/clang/AST/LambdaMangleContext.h deleted file mode 100644 index bbaee26..0000000 --- a/contrib/llvm/tools/clang/include/clang/AST/LambdaMangleContext.h +++ /dev/null @@ -1,38 +0,0 @@ -//===--- LambdaMangleContext.h - Context for mangling lambdas ---*- 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 LambdaMangleContext interface, which keeps track of -// the Itanium C++ ABI mangling numbers for lambda expressions. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LAMBDAMANGLECONTEXT_H -#define LLVM_CLANG_LAMBDAMANGLECONTEXT_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" - -namespace clang { - -class CXXMethodDecl; -class FunctionProtoType; - -/// \brief Keeps track of the mangled names of lambda expressions within a -/// particular context. -class LambdaMangleContext : public RefCountedBase<LambdaMangleContext> { - llvm::DenseMap<const FunctionProtoType *, unsigned> ManglingNumbers; - -public: - /// \brief Retrieve the mangling number of a new lambda expression with the - /// given call operator within this lambda context. - unsigned getManglingNumber(CXXMethodDecl *CallOperator); -}; - -} // end namespace clang -#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/Mangle.h b/contrib/llvm/tools/clang/include/clang/AST/Mangle.h index b6d22cf..c4d0d22 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Mangle.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Mangle.h @@ -19,6 +19,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" namespace clang { @@ -64,18 +65,29 @@ private: /// MangleContext - Context for tracking state which persists across multiple /// calls to the C++ name mangler. class MangleContext { +public: + enum ManglerKind { + MK_Itanium, + MK_Microsoft + }; + +private: virtual void anchor(); ASTContext &Context; DiagnosticsEngine &Diags; + const ManglerKind Kind; llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds; llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds; - + public: + ManglerKind getKind() const { return Kind; } + explicit MangleContext(ASTContext &Context, - DiagnosticsEngine &Diags) - : Context(Context), Diags(Diags) { } + DiagnosticsEngine &Diags, + ManglerKind Kind) + : Context(Context), Diags(Diags), Kind(Kind) {} virtual ~MangleContext() { } @@ -96,8 +108,12 @@ public: /// @name Mangler Entry Points /// @{ - virtual bool shouldMangleDeclName(const NamedDecl *D) = 0; - virtual void mangleName(const NamedDecl *D, raw_ostream &)=0; + bool shouldMangleDeclName(const NamedDecl *D); + virtual bool shouldMangleCXXName(const NamedDecl *D) = 0; + + // FIXME: consider replacing raw_ostream & with something like SmallString &. + void mangleName(const NamedDecl *D, raw_ostream &); + virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) = 0; @@ -106,13 +122,6 @@ public: raw_ostream &) = 0; virtual void mangleReferenceTemporary(const VarDecl *D, raw_ostream &) = 0; - virtual void mangleCXXVTable(const CXXRecordDecl *RD, - raw_ostream &) = 0; - virtual void mangleCXXVTT(const CXXRecordDecl *RD, - raw_ostream &) = 0; - virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, - const CXXRecordDecl *Type, - raw_ostream &) = 0; virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, @@ -129,36 +138,78 @@ public: const BlockDecl *BD, raw_ostream &Out); void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out); - // Do the right thing. - void mangleBlock(const BlockDecl *BD, raw_ostream &Out, - const NamedDecl *ID=0); - void mangleObjCMethodName(const ObjCMethodDecl *MD, - raw_ostream &); + void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); - // This is pretty lame. - virtual void mangleItaniumGuardVariable(const VarDecl *D, - raw_ostream &) { - llvm_unreachable("Target does not support mangling guard variables"); - } - // FIXME: Revisit this once we know what we need to do for MSVC compatibility. + virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; + + virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0; + + virtual void mangleDynamicAtExitDestructor(const VarDecl *D, + raw_ostream &) = 0; + + /// Generates a unique string for an externally visible type for use with TBAA + /// or type uniquing. + /// TODO: Extend this to internal types by generating names that are unique + /// across translation units so it can be used with LTO. + virtual void mangleTypeName(QualType T, raw_ostream &) = 0; + + /// @} +}; + +class ItaniumMangleContext : public MangleContext { +public: + explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D) + : MangleContext(C, D, MK_Itanium) {} + + virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; + virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0; + virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, + const CXXRecordDecl *Type, + raw_ostream &) = 0; virtual void mangleItaniumThreadLocalInit(const VarDecl *D, - raw_ostream &) { - llvm_unreachable("Target does not support mangling thread_local variables"); - } + raw_ostream &) = 0; virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D, - raw_ostream &) { - llvm_unreachable("Target does not support mangling thread_local variables"); + raw_ostream &) = 0; + + static bool classof(const MangleContext *C) { + return C->getKind() == MK_Itanium; } - /// @} + static ItaniumMangleContext *create(ASTContext &Context, + DiagnosticsEngine &Diags); }; -MangleContext *createItaniumMangleContext(ASTContext &Context, - DiagnosticsEngine &Diags); -MangleContext *createMicrosoftMangleContext(ASTContext &Context, - DiagnosticsEngine &Diags); +class MicrosoftMangleContext : public MangleContext { +public: + explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D) + : MangleContext(C, D, MK_Microsoft) {} + + /// \brief Mangle vftable symbols. Only a subset of the bases along the path + /// to the vftable are included in the name. It's up to the caller to pick + /// them correctly. + virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, + ArrayRef<const CXXRecordDecl *> BasePath, + raw_ostream &Out) = 0; + + /// \brief Mangle vbtable symbols. Only a subset of the bases along the path + /// to the vbtable are included in the name. It's up to the caller to pick + /// them correctly. + virtual void mangleCXXVBTable(const CXXRecordDecl *Derived, + ArrayRef<const CXXRecordDecl *> BasePath, + raw_ostream &Out) = 0; + + virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, + uint64_t OffsetInVFTable, + raw_ostream &) = 0; + static bool classof(const MangleContext *C) { + return C->getKind() == MK_Microsoft; + } + + static MicrosoftMangleContext *create(ASTContext &Context, + DiagnosticsEngine &Diags); +}; } #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/MangleNumberingContext.h b/contrib/llvm/tools/clang/include/clang/AST/MangleNumberingContext.h new file mode 100644 index 0000000..5a227f2 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/MangleNumberingContext.h @@ -0,0 +1,59 @@ +//=== MangleNumberingContext.h - Context for mangling numbers ---*- 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 LambdaBlockMangleContext interface, which keeps track +// of the Itanium C++ ABI mangling numbers for lambda expressions and block +// literals. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_MANGLENUMBERINGCONTEXT_H +#define LLVM_CLANG_MANGLENUMBERINGCONTEXT_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" + +namespace clang { + +class BlockDecl; +class CXXMethodDecl; +class IdentifierInfo; +class TagDecl; +class Type; +class VarDecl; + +/// \brief Keeps track of the mangled names of lambda expressions and block +/// literals within a particular context. +class MangleNumberingContext + : public RefCountedBase<MangleNumberingContext> { + llvm::DenseMap<const Type *, unsigned> ManglingNumbers; + llvm::DenseMap<IdentifierInfo*, unsigned> TagManglingNumbers; + +public: + virtual ~MangleNumberingContext() {} + + /// \brief Retrieve the mangling number of a new lambda expression with the + /// given call operator within this context. + unsigned getManglingNumber(const CXXMethodDecl *CallOperator); + + /// \brief Retrieve the mangling number of a new block literal within this + /// context. + unsigned getManglingNumber(const BlockDecl *BD); + + /// \brief Retrieve the mangling number of a static local variable within + /// this context. + virtual unsigned getManglingNumber(const VarDecl *VD) = 0; + + /// \brief Retrieve the mangling number of a static local variable within + /// this context. + unsigned getManglingNumber(const TagDecl *TD); +}; + +} // end namespace clang +#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h index 58f3986..b332b15 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h +++ b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h @@ -231,7 +231,11 @@ public: /// \brief Evalutes true when this nested-name-specifier location is /// non-empty. - operator bool() const { return Qualifier; } + LLVM_EXPLICIT operator bool() const { return Qualifier; } + + /// \brief Evalutes true when this nested-name-specifier location is + /// empty. + bool hasQualifier() const { return Qualifier; } /// \brief Retrieve the nested-name-specifier to which this instance /// refers. diff --git a/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h b/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h index 62eae02..bd2ebf5 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ParentMap.h @@ -29,6 +29,11 @@ public: /// visited and updated or inserted but not the parents of S. void addStmt(Stmt* S); + /// Manually sets the parent of \p S to \p Parent. + /// + /// If \p S is already in the map, this method will update the mapping. + void setParent(const Stmt *S, const Stmt *Parent); + Stmt *getParent(Stmt*) const; Stmt *getParentIgnoreParens(Stmt *) const; Stmt *getParentIgnoreParenCasts(Stmt *) const; diff --git a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h index e3c09e7..7642699 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h @@ -39,8 +39,9 @@ struct PrintingPolicy { SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false), SuppressUnwrittenScope(false), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), - SuppressStrongLifetime(false), Bool(LO.Bool), - TerseOutput(false), PolishForDeclaration(false) { } + SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), + Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false), + MSWChar(LO.MicrosoftExt && !LO.WChar) { } /// \brief What language we're printing. LangOptions LangOpts; @@ -131,6 +132,10 @@ struct PrintingPolicy { /// ARC. unsigned SuppressStrongLifetime : 1; + /// \brief When true, suppress printing of lifetime qualifier in + /// ARC. + unsigned SuppressLifetimeQualifiers : 1; + /// \brief Whether we can use 'bool' rather than '_Bool', even if the language /// doesn't actually have 'bool' (because, e.g., it is defined as a macro). unsigned Bool : 1; @@ -146,6 +151,10 @@ struct PrintingPolicy { /// declaration tag; such as, do not print attributes attached to the declaration. /// unsigned PolishForDeclaration : 1; + + /// \brief When true, print the built-in wchar_t type as __wchar_t. For use in + /// Microsoft mode when wchar_t is not available. + unsigned MSWChar : 1; }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h b/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h index 84a6e96..a4fcc10 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RawCommentList.h @@ -107,12 +107,9 @@ public: return RawText; } - SourceRange getSourceRange() const LLVM_READONLY { - return Range; - } - - unsigned getBeginLine(const SourceManager &SM) const; - unsigned getEndLine(const SourceManager &SM) const; + SourceRange getSourceRange() const LLVM_READONLY { return Range; } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } const char *getBriefText(const ASTContext &Context) const { if (BriefTextValid) @@ -146,11 +143,6 @@ private: /// considered as documentation comments. bool ParseAllComments : 1; - mutable bool BeginLineValid : 1; ///< True if BeginLine is valid - mutable bool EndLineValid : 1; ///< True if EndLine is valid - mutable unsigned BeginLine; ///< Cached line number - mutable unsigned EndLine; ///< Cached line number - /// \brief Constructor for AST deserialization. RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, bool IsAlmostTrailingComment, @@ -158,8 +150,7 @@ private: Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K), IsAttached(false), IsTrailingComment(IsTrailingComment), IsAlmostTrailingComment(IsAlmostTrailingComment), - ParseAllComments(ParseAllComments), - BeginLineValid(false), EndLineValid(false) + ParseAllComments(ParseAllComments) { } StringRef getRawTextSlow(const SourceManager &SourceMgr) const; @@ -178,8 +169,7 @@ public: explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } bool operator()(const RawComment &LHS, const RawComment &RHS) { - return SM.isBeforeInTranslationUnit(LHS.getSourceRange().getBegin(), - RHS.getSourceRange().getBegin()); + return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart()); } bool operator()(const RawComment *LHS, const RawComment *RHS) { @@ -191,8 +181,7 @@ public: /// sorted in order of appearance in the translation unit. class RawCommentList { public: - RawCommentList(SourceManager &SourceMgr) : - SourceMgr(SourceMgr), OnlyWhitespaceSeen(true) { } + RawCommentList(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {} void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator); @@ -203,15 +192,9 @@ public: private: SourceManager &SourceMgr; std::vector<RawComment *> Comments; - SourceLocation PrevCommentEndLoc; - bool OnlyWhitespaceSeen; void addCommentsToFront(const std::vector<RawComment *> &C) { - size_t OldSize = Comments.size(); - Comments.resize(C.size() + OldSize); - std::copy_backward(Comments.begin(), Comments.begin() + OldSize, - Comments.end()); - std::copy(C.begin(), C.end(), Comments.begin()); + Comments.insert(Comments.begin(), C.begin(), C.end()); } friend class ASTReader; diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h index 3655646..7268b3a 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h @@ -93,10 +93,22 @@ private: /// HasOwnVFPtr - Does this class provide a virtual function table /// (vtable in Itanium, vftbl in Microsoft) that is independent from /// its base classes? - bool HasOwnVFPtr; // TODO: stash this somewhere more efficient + bool HasOwnVFPtr : 1; + + /// HasVFPtr - Does this class have a vftable that could be extended by + /// a derived class. The class may have inherited this pointer from + /// a primary base class. + bool HasExtendableVFPtr : 1; + + /// AlignAfterVBases - Force appropriate alignment after virtual bases are + /// laid out in MS-C++-ABI. + bool AlignAfterVBases : 1; /// PrimaryBase - The primary base info for this record. llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase; + + /// BaseSharingVBPtr - The base we share vbptr with. + const CXXRecordDecl *BaseSharingVBPtr; /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy; @@ -122,13 +134,16 @@ private: typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, - bool hasOwnVFPtr, CharUnits vbptroffset, + bool hasOwnVFPtr, bool hasExtendableVFPtr, + CharUnits vbptroffset, CharUnits datasize, const uint64_t *fieldoffsets, unsigned fieldcount, CharUnits nonvirtualsize, CharUnits nonvirtualalign, CharUnits SizeOfLargestEmptySubobject, const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual, + const CXXRecordDecl *BaseSharingVBPtr, + bool ForceAlign, const BaseOffsetsMapTy& BaseOffsets, const VBaseOffsetsMapTy& VBaseOffsets); @@ -226,6 +241,37 @@ public: return CXXInfo->HasOwnVFPtr; } + /// hasVFPtr - Does this class have a virtual function table pointer + /// that can be extended by a derived class? This is synonymous with + /// this class having a VFPtr at offset zero. + bool hasExtendableVFPtr() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return CXXInfo->HasExtendableVFPtr; + } + + /// hasOwnVBPtr - Does this class provide its own virtual-base + /// table pointer, rather than inheriting one from a primary base + /// class? + /// + /// This implies that the ABI has no primary base class, meaning + /// that it has no base classes that are suitable under the conditions + /// of the ABI. + bool hasOwnVBPtr() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return hasVBPtr() && !CXXInfo->BaseSharingVBPtr; + } + + /// hasVBPtr - Does this class have a virtual function table pointer. + bool hasVBPtr() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return !CXXInfo->VBPtrOffset.isNegative(); + } + + bool getAlignAfterVBases() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return CXXInfo->AlignAfterVBases; + } + /// getVBPtrOffset - Get the offset for virtual base table pointer. /// This is only meaningful with the Microsoft ABI. CharUnits getVBPtrOffset() const { @@ -233,6 +279,11 @@ public: return CXXInfo->VBPtrOffset; } + const CXXRecordDecl *getBaseSharingVBPtr() const { + assert(CXXInfo && "Record layout does not have C++ specific info!"); + return CXXInfo->BaseSharingVBPtr; + } + const VBaseOffsetsMapTy &getVBaseOffsetsMap() const { assert(CXXInfo && "Record layout does not have C++ specific info!"); return CXXInfo->VBaseOffsets; diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h index b5a4b5e..d09550f 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h @@ -27,6 +27,7 @@ #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenMP.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -108,7 +109,7 @@ namespace clang { /// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar /// is Foo's super class) before calling VisitFoo(), the result is /// that the Visit*() methods for a given node are called in the -/// top-down order (e.g. for a node of type NamedDecl, the order will +/// top-down order (e.g. for a node of type NamespaceDecl, the order will /// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()). /// /// This scheme guarantees that all Visit*() calls for the same AST @@ -243,8 +244,16 @@ public: /// \brief Recursively visit a lambda capture. /// /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseLambdaCapture(LambdaExpr::Capture C); - + bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaExpr::Capture *C); + + /// \brief Recursively visit the body of a lambda expression. + /// + /// This provides a hook for visitors that need more context when visiting + /// \c LE->getBody(). + /// + /// \returns false if the visitation was terminated early, true otherwise. + bool TraverseLambdaBody(LambdaExpr *LE); + // ---- Methods on Stmts ---- // Declare Traverse*() for all concrete Stmt classes. @@ -342,7 +351,7 @@ public: // ---- Methods on TypeLocs ---- // FIXME: this currently just calls the matching Type methods - // Declare Traverse*() for all concrete Type classes. + // Declare Traverse*() for all concrete TypeLoc classes. #define ABSTRACT_TYPELOC(CLASS, BASE) #define TYPELOC(CLASS, BASE) \ bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL); @@ -398,8 +407,12 @@ public: private: // These are helper methods used by more than one Traverse* method. bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); - bool TraverseClassInstantiations(ClassTemplateDecl *D); - bool TraverseFunctionInstantiations(FunctionTemplateDecl *D) ; +#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \ + bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D); + DEF_TRAVERSE_TMPL_INST(Class) + DEF_TRAVERSE_TMPL_INST(Var) + DEF_TRAVERSE_TMPL_INST(Function) +#undef DEF_TRAVERSE_TMPL_INST bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL, unsigned Count); bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL); @@ -409,6 +422,13 @@ private: bool TraverseDeclContextHelper(DeclContext *DC); bool TraverseFunctionHelper(FunctionDecl *D); bool TraverseVarHelper(VarDecl *D); + bool TraverseOMPClause(OMPClause *C); +#define OPENMP_CLAUSE(Name, Class) \ + bool Visit##Class(Class *C); +#include "clang/Basic/OpenMPKinds.def" + /// \brief Process clauses with list of variables. + template <typename T> + void VisitOMPClauseList(T *Node); struct EnqueueJob { Stmt *S; @@ -802,10 +822,20 @@ bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer( } template<typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr::Capture C){ +bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture( + LambdaExpr *LE, const LambdaExpr::Capture *C) { + if (C->isInitCapture()) + TRY_TO(TraverseDecl(C->getCapturedVar())); + return true; +} + +template<typename Derived> +bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) { + TRY_TO(TraverseStmt(LE->getBody())); return true; } + // ----------------- Type traversal ----------------- // This macro makes available a variable T, the passed-in type. @@ -844,6 +874,10 @@ DEF_TRAVERSE_TYPE(MemberPointerType, { TRY_TO(TraverseType(T->getPointeeType())); }) +DEF_TRAVERSE_TYPE(DecayedType, { + TRY_TO(TraverseType(T->getOriginalType())); + }) + DEF_TRAVERSE_TYPE(ConstantArrayType, { TRY_TO(TraverseType(T->getElementType())); }) @@ -1050,6 +1084,10 @@ DEF_TRAVERSE_TYPELOC(MemberPointerType, { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) +DEF_TRAVERSE_TYPELOC(DecayedType, { + TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); + }) + template<typename Derived> bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) { // This isn't available for ArrayType, but is for the ArrayTypeLoc. @@ -1420,59 +1458,44 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper( return true; } -// A helper method for traversing the implicit instantiations of a -// class template. -template<typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations( - ClassTemplateDecl *D) { - ClassTemplateDecl::spec_iterator end = D->spec_end(); - for (ClassTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) { - ClassTemplateSpecializationDecl* SD = *it; - - switch (SD->getSpecializationKind()) { - // Visit the implicit instantiations with the requested pattern. - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - TRY_TO(TraverseDecl(SD)); - break; - - // We don't need to do anything on an explicit instantiation - // or explicit specialization because there will be an explicit - // node for it elsewhere. - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - case TSK_ExplicitSpecialization: - break; - } - } - - return true; +#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \ +/* A helper method for traversing the implicit instantiations of a + class or variable template. */ \ +template<typename Derived> \ +bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations( \ + TMPLDECLKIND##TemplateDecl *D) { \ + TMPLDECLKIND##TemplateDecl::spec_iterator end = D->spec_end(); \ + for (TMPLDECLKIND##TemplateDecl::spec_iterator it = D->spec_begin(); \ + it != end; ++it) { \ + TMPLDECLKIND##TemplateSpecializationDecl* SD = *it; \ + \ + switch (SD->getSpecializationKind()) { \ + /* Visit the implicit instantiations with the requested pattern. */ \ + case TSK_Undeclared: \ + case TSK_ImplicitInstantiation: \ + TRY_TO(TraverseDecl(SD)); \ + break; \ + \ + /* We don't need to do anything on an explicit instantiation + or explicit specialization because there will be an explicit + node for it elsewhere. */ \ + case TSK_ExplicitInstantiationDeclaration: \ + case TSK_ExplicitInstantiationDefinition: \ + case TSK_ExplicitSpecialization: \ + break; \ + } \ + } \ + \ + return true; \ } - -DEF_TRAVERSE_DECL(ClassTemplateDecl, { - CXXRecordDecl* TempDecl = D->getTemplatedDecl(); - TRY_TO(TraverseDecl(TempDecl)); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // class templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the class instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseClassInstantiations(D)); - - // Note that getInstantiatedFromMemberTemplate() is just a link - // from a template instantiation back to the template from which - // it was instantiated, and thus should not be traversed. - }) + +DEF_TRAVERSE_TMPL_INST(Class) +DEF_TRAVERSE_TMPL_INST(Var) // A helper method for traversing the instantiations of a // function while skipping its specializations. template<typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations( +bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations( FunctionTemplateDecl *D) { FunctionTemplateDecl::spec_iterator end = D->spec_end(); for (FunctionTemplateDecl::spec_iterator it = D->spec_begin(); it != end; @@ -1500,20 +1523,31 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations( return true; } -DEF_TRAVERSE_DECL(FunctionTemplateDecl, { - TRY_TO(TraverseDecl(D->getTemplatedDecl())); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // function templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the function instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseFunctionInstantiations(D)); - }) +// This macro unifies the traversal of class, variable and function +// template declarations. +#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \ +DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \ + TRY_TO(TraverseDecl(D->getTemplatedDecl())); \ + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \ + \ + /* By default, we do not traverse the instantiations of + class templates since they do not appear in the user code. The + following code optionally traverses them. + + We only traverse the class instantiations when we see the canonical + declaration of the template, to ensure we only visit them once. */ \ + if (getDerived().shouldVisitTemplateInstantiations() && \ + D == D->getCanonicalDecl()) \ + TRY_TO(TraverseTemplateInstantiations(D)); \ + \ + /* Note that getInstantiatedFromMemberTemplate() is just a link + from a template instantiation back to the template from which + it was instantiated, and thus should not be traversed. */ \ + }) + +DEF_TRAVERSE_TMPL_DECL(Class) +DEF_TRAVERSE_TMPL_DECL(Var) +DEF_TRAVERSE_TMPL_DECL(Function) DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, { // D is the "T" in something like @@ -1607,26 +1641,30 @@ DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); }) -DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, { - // For implicit instantiations ("set<int> x;"), we don't want to - // recurse at all, since the instatiated class isn't written in - // the source code anywhere. (Note the instatiated *type* -- - // set<int> -- is written, and will still get a callback of - // TemplateSpecializationType). For explicit instantiations - // ("template set<int>;"), we do need a callback, since this - // is the only callback that's made for this instantiation. - // We use getTypeAsWritten() to distinguish. - if (TypeSourceInfo *TSI = D->getTypeAsWritten()) - TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); - - if (!getDerived().shouldVisitTemplateInstantiations() && - D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) - // Returning from here skips traversing the - // declaration context of the ClassTemplateSpecializationDecl - // (embedded in the DEF_TRAVERSE_DECL() macro) - // which contains the instantiated members of the class. - return true; - }) +#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \ +DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \ + /* For implicit instantiations ("set<int> x;"), we don't want to + recurse at all, since the instatiated template isn't written in + the source code anywhere. (Note the instatiated *type* -- + set<int> -- is written, and will still get a callback of + TemplateSpecializationType). For explicit instantiations + ("template set<int>;"), we do need a callback, since this + is the only callback that's made for this instantiation. + We use getTypeAsWritten() to distinguish. */ \ + if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \ + TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \ + \ + if (!getDerived().shouldVisitTemplateInstantiations() && \ + D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \ + /* Returning from here skips traversing the + declaration context of the *TemplateSpecializationDecl + (embedded in the DEF_TRAVERSE_DECL() macro) + which contains the instantiated members of the template. */ \ + return true; \ + }) + +DEF_TRAVERSE_TMPL_SPEC_DECL(Class) +DEF_TRAVERSE_TMPL_SPEC_DECL(Var) template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper( @@ -1637,25 +1675,30 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper( return true; } -DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, { - // The partial specialization. - if (TemplateParameterList *TPL = D->getTemplateParameters()) { - for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); - I != E; ++I) { - TRY_TO(TraverseDecl(*I)); - } - } - // The args that remains unspecialized. - TRY_TO(TraverseTemplateArgumentLocsHelper( - D->getTemplateArgsAsWritten(), D->getNumTemplateArgsAsWritten())); - - // Don't need the ClassTemplatePartialSpecializationHelper, even - // though that's our parent class -- we already visit all the - // template args here. - TRY_TO(TraverseCXXRecordHelper(D)); - - // Instantiations will have been visited with the primary template. - }) +#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \ +DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \ + /* The partial specialization. */ \ + if (TemplateParameterList *TPL = D->getTemplateParameters()) { \ + for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \ + I != E; ++I) { \ + TRY_TO(TraverseDecl(*I)); \ + } \ + } \ + /* The args that remains unspecialized. */ \ + TRY_TO(TraverseTemplateArgumentLocsHelper( \ + D->getTemplateArgsAsWritten()->getTemplateArgs(), \ + D->getTemplateArgsAsWritten()->NumTemplateArgs)); \ + \ + /* Don't need the *TemplatePartialSpecializationHelper, even + though that's our parent class -- we already visit all the + template args here. */ \ + TRY_TO(Traverse##DECLKIND##Helper(D)); \ + \ + /* Instantiations will have been visited with the primary template. */ \ + }) + +DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord) +DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var) DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); @@ -1736,6 +1779,14 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { // including exception specifications. if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) { TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); + } else if (getDerived().shouldVisitImplicitCode()) { + // Visit parameter variable declarations of the implicit function + // if the traverser is visiting implicit code. Parameter variable + // declarations do not have valid TypeSourceInfo, so to visit them + // we need to traverse the declarations explicitly. + for (FunctionDecl::param_const_iterator I = D->param_begin(), + E = D->param_end(); I != E; ++I) + TRY_TO(TraverseDecl(*I)); } if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) { @@ -2117,10 +2168,12 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, { // Walk only the visible parts of lambda expressions. template<typename Derived> bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) { + TRY_TO(WalkUpFromLambdaExpr(S)); + for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(), CEnd = S->explicit_capture_end(); C != CEnd; ++C) { - TRY_TO(TraverseLambdaCapture(*C)); + TRY_TO(TraverseLambdaCapture(S, C)); } if (S->hasExplicitParameters() || S->hasExplicitResultType()) { @@ -2140,7 +2193,7 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) { } } - TRY_TO(TraverseStmt(S->getBody())); + TRY_TO(TraverseLambdaBody(S)); return true; } @@ -2174,6 +2227,7 @@ DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { }) DEF_TRAVERSE_STMT(CXXDeleteExpr, { }) DEF_TRAVERSE_STMT(ExprWithCleanups, { }) DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { }) +DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { }) DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo()) @@ -2211,6 +2265,7 @@ DEF_TRAVERSE_STMT(ParenExpr, { }) DEF_TRAVERSE_STMT(ParenListExpr, { }) DEF_TRAVERSE_STMT(PredefinedExpr, { }) DEF_TRAVERSE_STMT(ShuffleVectorExpr, { }) +DEF_TRAVERSE_STMT(ConvertVectorExpr, { }) DEF_TRAVERSE_STMT(StmtExpr, { }) DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); @@ -2269,6 +2324,61 @@ DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { }) // Traverse OpenCL: AsType, Convert. DEF_TRAVERSE_STMT(AsTypeExpr, { }) +// OpenMP directives. +DEF_TRAVERSE_STMT(OMPParallelDirective, { + ArrayRef<OMPClause *> Clauses = S->clauses(); + for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); + I != E; ++I) + if (!TraverseOMPClause(*I)) return false; +}) + +// OpenMP clauses. +template<typename Derived> +bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { + if (!C) return true; + switch (C->getClauseKind()) { +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_##Name: \ + return getDerived().Visit##Class(static_cast<Class*>(C)); +#include "clang/Basic/OpenMPKinds.def" + default: break; + } + return true; +} + +template<typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) { + return true; +} + +template<typename Derived> +template<typename T> +void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { + for (typename T::varlist_iterator I = Node->varlist_begin(), + E = Node->varlist_end(); + I != E; ++I) + TraverseStmt(*I); +} + +template<typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) { + VisitOMPClauseList(C); + return true; +} + +template<typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause( + OMPFirstprivateClause *C) { + VisitOMPClauseList(C); + return true; +} + +template<typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) { + VisitOMPClauseList(C); + return true; +} + // FIXME: look at the following tricky-seeming exprs to see if we // need to recurse on anything. These are ones that have methods // returning decls or qualtypes or nestednamespecifier -- though I'm diff --git a/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h b/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h index e3b340a..cfe5a90 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h @@ -75,7 +75,7 @@ public: /// \brief Return the first declaration of this declaration or itself if this /// is the only declaration. - decl_type *getFirstDeclaration() { + decl_type *getFirstDecl() { decl_type *D = static_cast<decl_type*>(this); while (D->getPreviousDecl()) D = D->getPreviousDecl(); @@ -84,31 +84,29 @@ public: /// \brief Return the first declaration of this declaration or itself if this /// is the only declaration. - const decl_type *getFirstDeclaration() const { + const decl_type *getFirstDecl() const { const decl_type *D = static_cast<const decl_type*>(this); while (D->getPreviousDecl()) D = D->getPreviousDecl(); return D; } - /// \brief Returns true if this is the first declaration. - bool isFirstDeclaration() const { - return RedeclLink.NextIsLatest(); - } + /// \brief True if this is the first declaration in its redeclaration chain. + bool isFirstDecl() const { return RedeclLink.NextIsLatest(); } /// \brief Returns the most recent (re)declaration of this declaration. decl_type *getMostRecentDecl() { - return getFirstDeclaration()->RedeclLink.getNext(); + return getFirstDecl()->RedeclLink.getNext(); } /// \brief Returns the most recent (re)declaration of this declaration. const decl_type *getMostRecentDecl() const { - return getFirstDeclaration()->RedeclLink.getNext(); + return getFirstDecl()->RedeclLink.getNext(); } /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the /// first and only declaration. - void setPreviousDeclaration(decl_type *PrevDecl); + void setPreviousDecl(decl_type *PrevDecl); /// \brief Iterates through all the redeclarations of the same decl. class redecl_iterator { @@ -134,7 +132,7 @@ public: redecl_iterator& operator++() { assert(Current && "Advancing while iterator has reached end"); // Sanity check to avoid infinite loop on invalid redecl chain. - if (Current->isFirstDeclaration()) { + if (Current->isFirstDecl()) { if (PassedFirst) { assert(0 && "Passed first decl twice, invalid redecl chain!"); Current = 0; @@ -175,6 +173,40 @@ public: friend class ASTDeclWriter; }; +/// \brief Get the primary declaration for a declaration from an AST file. That +/// will be the first-loaded declaration. +Decl *getPrimaryMergedDecl(Decl *D); + +/// \brief Provides common interface for the Decls that cannot be redeclared, +/// but can be merged if the same declaration is brought in from multiple +/// modules. +template<typename decl_type> +class Mergeable { +public: + Mergeable() {} + + /// \brief Return the first declaration of this declaration or itself if this + /// is the only declaration. + decl_type *getFirstDecl() { + decl_type *D = static_cast<decl_type*>(this); + if (!D->isFromASTFile()) + return D; + return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D))); + } + + /// \brief Return the first declaration of this declaration or itself if this + /// is the only declaration. + const decl_type *getFirstDecl() const { + const decl_type *D = static_cast<const decl_type*>(this); + if (!D->isFromASTFile()) + return D; + return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D))); + } + + /// \brief Returns true if this is the first declaration. + bool isFirstDecl() const { return getFirstDecl() == this; } +}; + } #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h index 74c9ec2..ace53d8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h @@ -266,10 +266,6 @@ protected: /// Whether this initializer list originally had a GNU array-range /// designator in it. This is a temporary marker used by CodeGen. unsigned HadArrayRangeDesignator : 1; - - /// Whether this initializer list initializes a std::initializer_list - /// object. - unsigned InitializesStdInitializerList : 1; }; class TypeTraitExprBitfields { @@ -289,7 +285,7 @@ protected: /// \brief The number of arguments to this type trait. unsigned NumArgs : 32 - 8 - 1 - NumExprBits; }; - + union { // FIXME: this is wasteful on 64-bit platforms. void *Aligner; @@ -316,19 +312,21 @@ protected: public: // Only allow allocation of Stmts using the allocator in ASTContext // or by doing a placement new. - void* operator new(size_t bytes, ASTContext& C, - unsigned alignment = 8) throw(); + void* operator new(size_t bytes, const ASTContext& C, + unsigned alignment = 8); - void* operator new(size_t bytes, ASTContext* C, - unsigned alignment = 8) throw(); + void* operator new(size_t bytes, const ASTContext* C, + unsigned alignment = 8) { + return operator new(bytes, *C, alignment); + } void* operator new(size_t bytes, void* mem) throw() { return mem; } - void operator delete(void*, ASTContext&, unsigned) throw() { } - void operator delete(void*, ASTContext*, unsigned) throw() { } - void operator delete(void*, std::size_t) throw() { } + void operator delete(void*, const ASTContext&, unsigned) throw() { } + void operator delete(void*, const ASTContext*, unsigned) throw() { } + void operator delete(void*, size_t) throw() { } void operator delete(void*, void*) throw() { } public: @@ -382,7 +380,7 @@ public: /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST /// back to its original source language syntax. - void dumpPretty(ASTContext &Context) const; + void dumpPretty(const ASTContext &Context) const; void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation = 0) const; @@ -401,13 +399,6 @@ public: const_cast<const Stmt*>(this)->stripLabelLikeStatements()); } - /// 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 - /// such implicit control-flow. Such statements are also specially handled - /// within CFGs. - bool hasImplicitControlFlow() const; - /// Child Iterators: All subclasses must implement 'children' /// to permit easy iteration over the substatements/subexpessions of an /// AST node. This permits easy iteration over all nodes in the AST. @@ -553,10 +544,10 @@ class CompoundStmt : public Stmt { Stmt** Body; SourceLocation LBracLoc, RBracLoc; public: - CompoundStmt(ASTContext &C, ArrayRef<Stmt*> Stmts, + CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts, SourceLocation LB, SourceLocation RB); - // \brief Build an empty compound statment with a location. + // \brief Build an empty compound statement with a location. explicit CompoundStmt(SourceLocation Loc) : Stmt(CompoundStmtClass), Body(0), LBracLoc(Loc), RBracLoc(Loc) { CompoundStmtBits.NumStmts = 0; @@ -568,7 +559,7 @@ public: CompoundStmtBits.NumStmts = 0; } - void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts); + void setStmts(const ASTContext &C, Stmt **Stmts, unsigned NumStmts); bool body_empty() const { return CompoundStmtBits.NumStmts == 0; } unsigned size() const { return CompoundStmtBits.NumStmts; } @@ -827,10 +818,10 @@ class AttributedStmt : public Stmt { } public: - static AttributedStmt *Create(ASTContext &C, SourceLocation Loc, + static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt); // \brief Build an empty attributed statement. - static AttributedStmt *CreateEmpty(ASTContext &C, unsigned NumAttrs); + static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs); SourceLocation getAttrLoc() const { return AttrLoc; } ArrayRef<const Attr*> getAttrs() const { @@ -860,7 +851,7 @@ class IfStmt : public Stmt { SourceLocation ElseLoc; public: - IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, + IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0); /// \brief Build an empty if/then/else statement @@ -875,7 +866,7 @@ public: /// } /// \endcode VarDecl *getConditionVariable() const; - void setConditionVariable(ASTContext &C, VarDecl *V); + void setConditionVariable(const ASTContext &C, VarDecl *V); /// If this IfStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. @@ -933,7 +924,7 @@ class SwitchStmt : public Stmt { unsigned AllEnumCasesCovered : 1; public: - SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond); + SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond); /// \brief Build a empty switch statement. explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } @@ -948,7 +939,7 @@ public: /// } /// \endcode VarDecl *getConditionVariable() const; - void setConditionVariable(ASTContext &C, VarDecl *V); + void setConditionVariable(const ASTContext &C, VarDecl *V); /// If this SwitchStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. @@ -967,9 +958,6 @@ public: SwitchCase *getSwitchCaseList() { return FirstCase; } /// \brief Set the case list for this switch statement. - /// - /// The caller is responsible for incrementing the retain counts on - /// all of the SwitchCase statements in this list. void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } SourceLocation getSwitchLoc() const { return SwitchLoc; } @@ -1021,7 +1009,7 @@ class WhileStmt : public Stmt { Stmt* SubExprs[END_EXPR]; SourceLocation WhileLoc; public: - WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, + WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL); /// \brief Build an empty while statement. @@ -1036,7 +1024,7 @@ public: /// } /// \endcode VarDecl *getConditionVariable() const; - void setConditionVariable(ASTContext &C, VarDecl *V); + void setConditionVariable(const ASTContext &C, VarDecl *V); /// If this WhileStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. @@ -1129,8 +1117,9 @@ class ForStmt : public Stmt { SourceLocation LParenLoc, RParenLoc; public: - ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, - Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP); + ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, + Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, + SourceLocation RP); /// \brief Build an empty for statement. explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { } @@ -1146,7 +1135,7 @@ public: /// } /// \endcode VarDecl *getConditionVariable() const; - void setConditionVariable(ASTContext &C, VarDecl *V); + void setConditionVariable(const ASTContext &C, VarDecl *V); /// If this ForStmt has a condition variable, return the faux DeclStmt /// associated with the creation of that condition variable. @@ -1417,7 +1406,7 @@ public: //===--- Asm String Analysis ---===// /// Assemble final IR asm string. - std::string generateAsmString(ASTContext &C) const; + std::string generateAsmString(const ASTContext &C) const; //===--- Output operands ---===// @@ -1520,7 +1509,7 @@ class GCCAsmStmt : public AsmStmt { friend class ASTStmtReader; public: - GCCAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, + GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, unsigned numoutputs, unsigned numinputs, IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, @@ -1586,10 +1575,10 @@ public: /// translation of strings from GCC syntax to LLVM IR syntax, and handles //// flattening of named references like %[foo] to Operand AsmStringPiece's. unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces, - ASTContext &C, unsigned &DiagOffs) const; + const ASTContext &C, unsigned &DiagOffs) const; /// Assemble final IR asm string. - std::string generateAsmString(ASTContext &C) const; + std::string generateAsmString(const ASTContext &C) const; //===--- Output operands ---===// @@ -1649,7 +1638,7 @@ public: } private: - void setOutputsAndInputsAndClobbers(ASTContext &C, + void setOutputsAndInputsAndClobbers(const ASTContext &C, IdentifierInfo **Names, StringLiteral **Constraints, Stmt **Exprs, @@ -1695,9 +1684,9 @@ class MSAsmStmt : public AsmStmt { friend class ASTStmtReader; public: - MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc, - bool issimple, bool isvolatile, ArrayRef<Token> asmtoks, - unsigned numoutputs, unsigned numinputs, + MSAsmStmt(const ASTContext &C, SourceLocation asmloc, + SourceLocation lbraceloc, bool issimple, bool isvolatile, + ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs, ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs, StringRef asmstr, ArrayRef<StringRef> clobbers, SourceLocation endloc); @@ -1720,7 +1709,7 @@ public: StringRef getAsmString() const { return AsmStr; } /// Assemble final IR asm string. - std::string generateAsmString(ASTContext &C) const; + std::string generateAsmString(const ASTContext &C) const; //===--- Output operands ---===// @@ -1765,12 +1754,9 @@ public: StringRef getClobber(unsigned i) const { return getClobbers()[i]; } private: - void initialize(ASTContext &C, - StringRef AsmString, - ArrayRef<Token> AsmToks, - ArrayRef<StringRef> Constraints, - ArrayRef<Expr*> Exprs, - ArrayRef<StringRef> Clobbers); + void initialize(const ASTContext &C, StringRef AsmString, + ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints, + ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers); public: SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; } @@ -1800,7 +1786,7 @@ class SEHExceptStmt : public Stmt { explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { } public: - static SEHExceptStmt* Create(ASTContext &C, + static SEHExceptStmt* Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block); @@ -1841,7 +1827,7 @@ class SEHFinallyStmt : public Stmt { explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { } public: - static SEHFinallyStmt* Create(ASTContext &C, + static SEHFinallyStmt* Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block); @@ -1880,10 +1866,8 @@ class SEHTryStmt : public Stmt { explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { } public: - static SEHTryStmt* Create(ASTContext &C, - bool isCXXTry, - SourceLocation TryLoc, - Stmt *TryBlock, + static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry, + SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler); SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } @@ -2006,13 +1990,13 @@ private: void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; } public: - static CapturedStmt *Create(ASTContext &Context, Stmt *S, + static CapturedStmt *Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures, ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD); - static CapturedStmt *CreateDeserialized(ASTContext &Context, + static CapturedStmt *CreateDeserialized(const ASTContext &Context, unsigned NumCaptures); /// \brief Retrieve the statement being captured. diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h index 0112bef..df98d41 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h @@ -79,10 +79,10 @@ class CXXTryStmt : public Stmt { } public: - static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc, + static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers); - static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty, + static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty, unsigned numHandlers); SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h b/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h index b933ed0..fbc8e5d 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_STMT_ITR_H #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Compiler.h" #include <cassert> #include <cstddef> #include <iterator> @@ -28,18 +29,14 @@ class VariableArrayType; class StmtIteratorBase { protected: - enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3, + enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2, Flags = 0x3 }; Stmt **stmt; - union { Decl *decl; Decl **DGI; }; + Decl **DGI; uintptr_t RawVAPtr; Decl **DGE; - bool inDecl() const { - return (RawVAPtr & Flags) == DeclMode; - } - bool inDeclGroup() const { return (RawVAPtr & Flags) == DeclGroupMode; } @@ -49,7 +46,7 @@ protected: } bool inStmt() const { - return (RawVAPtr & Flags) == 0; + return (RawVAPtr & Flags) == StmtMode; } const VariableArrayType *getVAPtr() const { @@ -57,7 +54,7 @@ protected: } void setVAPtr(const VariableArrayType *P) { - assert (inDecl() || inDeclGroup() || inSizeOfTypeVA()); + assert (inDeclGroup() || inSizeOfTypeVA()); RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags); } @@ -67,11 +64,10 @@ protected: Stmt*& GetDeclExpr() const; - StmtIteratorBase(Stmt **s) : stmt(s), decl(0), RawVAPtr(0) {} - StmtIteratorBase(Decl *d, Stmt **s); + StmtIteratorBase(Stmt **s) : stmt(s), DGI(0), RawVAPtr(0) {} StmtIteratorBase(const VariableArrayType *t); StmtIteratorBase(Decl **dgi, Decl **dge); - StmtIteratorBase() : stmt(0), decl(0), RawVAPtr(0) {} + StmtIteratorBase() : stmt(0), DGI(0), RawVAPtr(0) {} }; @@ -86,7 +82,6 @@ public: StmtIteratorImpl() {} StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {} StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {} - StmtIteratorImpl(Decl *d, Stmt **s) : StmtIteratorBase(d, s) {} StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {} DERIVED& operator++() { @@ -107,15 +102,15 @@ public: } bool operator==(const DERIVED& RHS) const { - return stmt == RHS.stmt && decl == RHS.decl && RawVAPtr == RHS.RawVAPtr; + return stmt == RHS.stmt && DGI == RHS.DGI && RawVAPtr == RHS.RawVAPtr; } bool operator!=(const DERIVED& RHS) const { - return stmt != RHS.stmt || decl != RHS.decl || RawVAPtr != RHS.RawVAPtr; + return stmt != RHS.stmt || DGI != RHS.DGI || RawVAPtr != RHS.RawVAPtr; } REFERENCE operator*() const { - return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr()); + return inStmt() ? *stmt : GetDeclExpr(); } REFERENCE operator->() const { return operator*(); } @@ -131,9 +126,6 @@ struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> { StmtIterator(const VariableArrayType *t) : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {} - - StmtIterator(Decl* D, Stmt **s = 0) - : StmtIteratorImpl<StmtIterator,Stmt*&>(D, s) {} }; struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator, @@ -156,7 +148,7 @@ struct StmtRange : std::pair<StmtIterator,StmtIterator> { : std::pair<StmtIterator,StmtIterator>(begin, end) {} bool empty() const { return first == second; } - operator bool() const { return !empty(); } + LLVM_EXPLICIT operator bool() const { return !empty(); } Stmt *operator->() const { return first.operator->(); } Stmt *&operator*() const { return first.operator*(); } @@ -199,7 +191,7 @@ struct ConstStmtRange : std::pair<ConstStmtIterator,ConstStmtIterator> { : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {} bool empty() const { return first == second; } - operator bool() const { return !empty(); } + LLVM_EXPLICIT operator bool() const { return !empty(); } const Stmt *operator->() const { return first.operator->(); } const Stmt *operator*() const { return first.operator*(); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h b/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h index e97c1a5..bfb4a9b 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtObjC.h @@ -181,13 +181,12 @@ private: HasFinally(HasFinally) { } public: - static ObjCAtTryStmt *Create(ASTContext &Context, SourceLocation atTryLoc, - Stmt *atTryStmt, + static ObjCAtTryStmt *Create(const ASTContext &Context, + SourceLocation atTryLoc, Stmt *atTryStmt, Stmt **CatchStmts, unsigned NumCatchStmts, Stmt *atFinallyStmt); - static ObjCAtTryStmt *CreateEmpty(ASTContext &Context, - unsigned NumCatchStmts, - bool HasFinally); + static ObjCAtTryStmt *CreateEmpty(const ASTContext &Context, + unsigned NumCatchStmts, bool HasFinally); /// \brief Retrieve the location of the @ in the \@try. SourceLocation getAtTryLoc() const { return AtTryLoc; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h b/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h new file mode 100644 index 0000000..8570d88 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h @@ -0,0 +1,528 @@ +//===- StmtOpenMP.h - Classes for OpenMP directives and clauses --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// \brief This file defines OpenMP AST classes for executable directives and +/// clauses. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_STMTOPENMP_H +#define LLVM_CLANG_AST_STMTOPENMP_H + +#include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/AST/Expr.h" +#include "clang/AST/Stmt.h" + +namespace clang { + +//===----------------------------------------------------------------------===// +// AST classes for clauses. +//===----------------------------------------------------------------------===// + +/// \brief This is a basic class for representing single OpenMP clause. +/// +class OMPClause { + /// \brief Starting location of the clause (the clause keyword). + SourceLocation StartLoc; + /// \brief Ending location of the clause. + SourceLocation EndLoc; + /// \brief Kind of the clause. + OpenMPClauseKind Kind; +protected: + OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc) + : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {} + +public: + + /// \brief Returns the starting location of the clause. + SourceLocation getLocStart() const { return StartLoc; } + /// \brief Returns the ending location of the clause. + SourceLocation getLocEnd() const { return EndLoc; } + + /// \brief Sets the starting location of the clause. + void setLocStart(SourceLocation Loc) { StartLoc = Loc; } + /// \brief Sets the ending location of the clause. + void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } + + /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.). + OpenMPClauseKind getClauseKind() const { return Kind; } + + bool isImplicit() const { return StartLoc.isInvalid();} + + StmtRange children(); + ConstStmtRange children() const { + return const_cast<OMPClause *>(this)->children(); + } + static bool classof(const OMPClause *T) { + return true; + } +}; + +/// \brief This represents clauses with the list of variables like 'private', +/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the +/// '#pragma omp ...' directives. +template <class T> +class OMPVarList { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Number of variables in the list. + unsigned NumVars; +protected: + /// \brief Fetches list of variables associated with this clause. + llvm::MutableArrayRef<Expr *> getVarRefs() { + return llvm::MutableArrayRef<Expr *>( + reinterpret_cast<Expr **>(static_cast<T *>(this) + 1), + NumVars); + } + + /// \brief Sets the list of variables for this clause. + void setVarRefs(ArrayRef<Expr *> VL) { + assert(VL.size() == NumVars && + "Number of variables is not the same as the preallocated buffer"); + std::copy(VL.begin(), VL.end(), + reinterpret_cast<Expr **>(static_cast<T *>(this) + 1)); + } + + /// \brief Build clause with number of variables \a N. + /// + /// \param N Number of the variables in the clause. + /// + OMPVarList(SourceLocation LParenLoc, unsigned N) + : LParenLoc(LParenLoc), NumVars(N) { } +public: + typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator; + typedef ArrayRef<const Expr *>::iterator varlist_const_iterator; + + unsigned varlist_size() const { return NumVars; } + bool varlist_empty() const { return NumVars == 0; } + varlist_iterator varlist_begin() { return getVarRefs().begin(); } + varlist_iterator varlist_end() { return getVarRefs().end(); } + varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); } + varlist_const_iterator varlist_end() const { return getVarRefs().end(); } + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Fetches list of all variables in the clause. + ArrayRef<const Expr *> getVarRefs() const { + return ArrayRef<const Expr *>( + reinterpret_cast<const Expr *const *>(static_cast<const T *>(this) + 1), + NumVars); + } +}; + +/// \brief This represents 'default' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp parallel default(shared) +/// \endcode +/// In this example directive '#pragma omp parallel' has simple 'default' +/// clause with kind 'shared'. +/// +class OMPDefaultClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief A kind of the 'default' clause. + OpenMPDefaultClauseKind Kind; + /// \brief Start location of the kind in source code. + SourceLocation KindKwLoc; + + /// \brief Set kind of the clauses. + /// + /// \param K Argument of clause. + /// + void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; } + + /// \brief Set argument location. + /// + /// \param KLoc Argument location. + /// + void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } +public: + /// \brief Build 'default' clause with argument \a A ('none' or 'shared'). + /// + /// \param A Argument of the clause ('none' or 'shared'). + /// \param ALoc Starting location of the argument. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// + OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), + Kind(A), KindKwLoc(ALoc) { } + + /// \brief Build an empty clause. + /// + OMPDefaultClause() + : OMPClause(OMPC_default, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown), + KindKwLoc(SourceLocation()) { } + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Returns kind of the clause. + OpenMPDefaultClauseKind getDefaultKind() const { return Kind; } + + /// \brief Returns location of clause kind. + SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_default; + } + + StmtRange children() { + return StmtRange(); + } +}; + +/// \brief This represents clause 'private' in the '#pragma omp ...' directives. +/// +/// \code +/// #pragma omp parallel private(a,b) +/// \endcode +/// In this example directive '#pragma omp parallel' has clause 'private' +/// with the variables 'a' and 'b'. +/// +class OMPPrivateClause : public OMPClause, public OMPVarList<OMPPrivateClause> { + /// \brief Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + /// + OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPClause(OMPC_private, StartLoc, EndLoc), + OMPVarList<OMPPrivateClause>(LParenLoc, N) { } + + /// \brief Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPPrivateClause(unsigned N) + : OMPClause(OMPC_private, SourceLocation(), SourceLocation()), + OMPVarList<OMPPrivateClause>(SourceLocation(), N) { } +public: + /// \brief Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + /// + static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, + ArrayRef<Expr *> VL); + /// \brief Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N); + + StmtRange children() { + return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_private; + } +}; + +/// \brief This represents clause 'firstprivate' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp parallel firstprivate(a,b) +/// \endcode +/// In this example directive '#pragma omp parallel' has clause 'firstprivate' +/// with the variables 'a' and 'b'. +/// +class OMPFirstprivateClause : public OMPClause, + public OMPVarList<OMPFirstprivateClause> { + /// \brief Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + /// + OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPClause(OMPC_firstprivate, StartLoc, EndLoc), + OMPVarList<OMPFirstprivateClause>(LParenLoc, N) { } + + /// \brief Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPFirstprivateClause(unsigned N) + : OMPClause(OMPC_firstprivate, SourceLocation(), SourceLocation()), + OMPVarList<OMPFirstprivateClause>(SourceLocation(), N) { } +public: + /// \brief Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + /// + static OMPFirstprivateClause *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, + ArrayRef<Expr *> VL); + /// \brief Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N); + + StmtRange children() { + return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_firstprivate; + } +}; + +/// \brief This represents clause 'shared' in the '#pragma omp ...' directives. +/// +/// \code +/// #pragma omp parallel shared(a,b) +/// \endcode +/// In this example directive '#pragma omp parallel' has clause 'shared' +/// with the variables 'a' and 'b'. +/// +class OMPSharedClause : public OMPClause, public OMPVarList<OMPSharedClause> { + /// \brief Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + /// + OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPClause(OMPC_shared, StartLoc, EndLoc), + OMPVarList<OMPSharedClause>(LParenLoc, N) { } + + /// \brief Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPSharedClause(unsigned N) + : OMPClause(OMPC_shared, SourceLocation(), SourceLocation()), + OMPVarList<OMPSharedClause>(SourceLocation(), N) { } +public: + /// \brief Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + /// + static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef<Expr *> VL); + /// \brief Creates an empty clause with \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N); + + StmtRange children() { + return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_shared; + } +}; + +//===----------------------------------------------------------------------===// +// AST classes for directives. +//===----------------------------------------------------------------------===// + +/// \brief This is a basic class for representing single OpenMP executable +/// directive. +/// +class OMPExecutableDirective : public Stmt { + friend class ASTStmtReader; + /// \brief Kind of the directive. + OpenMPDirectiveKind Kind; + /// \brief Starting location of the directive (directive keyword). + SourceLocation StartLoc; + /// \brief Ending location of the directive. + SourceLocation EndLoc; + /// \brief Pointer to the list of clauses. + llvm::MutableArrayRef<OMPClause *> Clauses; + /// \brief Associated statement (if any) and expressions. + llvm::MutableArrayRef<Stmt *> StmtAndExpressions; +protected: + /// \brief Build instance of directive of class \a K. + /// + /// \param SC Statement class. + /// \param K Kind of OpenMP directive. + /// \param StartLoc Starting location of the directive (directive keyword). + /// \param EndLoc Ending location of the directive. + /// + template <typename T> + OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, + SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses, unsigned NumberOfExpressions) + : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc), + Clauses(reinterpret_cast<OMPClause **>(static_cast<T *>(this) + 1), + NumClauses), + StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()), + NumberOfExpressions) { } + + /// \brief Sets the list of variables for this clause. + /// + /// \param Clauses The list of clauses for the directive. + /// + void setClauses(ArrayRef<OMPClause *> Clauses); + + /// \brief Set the associated statement for the directive. + /// + /// /param S Associated statement. + /// + void setAssociatedStmt(Stmt *S) { + StmtAndExpressions[0] = S; + } + +public: + /// \brief Returns starting location of directive kind. + SourceLocation getLocStart() const { return StartLoc; } + /// \brief Returns ending location of directive. + SourceLocation getLocEnd() const { return EndLoc; } + + /// \brief Set starting location of directive kind. + /// + /// \param Loc New starting location of directive. + /// + void setLocStart(SourceLocation Loc) { StartLoc = Loc; } + /// \brief Set ending location of directive. + /// + /// \param Loc New ending location of directive. + /// + void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } + + /// \brief Get number of clauses. + unsigned getNumClauses() const { return Clauses.size(); } + + /// \brief Returns specified clause. + /// + /// \param i Number of clause. + /// + OMPClause *getClause(unsigned i) const { + assert(i < Clauses.size() && "index out of bound!"); + return Clauses[i]; + } + + /// \brief Returns statement associated with the directive. + Stmt *getAssociatedStmt() const { + return StmtAndExpressions[0]; + } + + OpenMPDirectiveKind getDirectiveKind() const { return Kind; } + + static bool classof(const Stmt *S) { + return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && + S->getStmtClass() <= lastOMPExecutableDirectiveConstant; + } + + child_range children() { + return child_range(StmtAndExpressions.begin(), StmtAndExpressions.end()); + } + + ArrayRef<OMPClause *> clauses() { return Clauses; } + + ArrayRef<OMPClause *> clauses() const { return Clauses; } +}; + +/// \brief This represents '#pragma omp parallel' directive. +/// +/// \code +/// #pragma omp parallel private(a,b) reduction(+: c,d) +/// \endcode +/// In this example directive '#pragma omp parallel' has clauses 'private' +/// with the variables 'a' and 'b' and 'reduction' with operator '+' and +/// variables 'c' and 'd'. +/// +class OMPParallelDirective : public OMPExecutableDirective { + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive (directive keyword). + /// \param EndLoc Ending Location of the directive. + /// + OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned N) + : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, + StartLoc, EndLoc, N, 1) { } + + /// \brief Build an empty directive. + /// + /// \param N Number of clauses. + /// + explicit OMPParallelDirective(unsigned N) + : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, + SourceLocation(), SourceLocation(), N, 1) { } +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement associated with the directive. + /// + static OMPParallelDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place for \a N clauses. + /// + /// \param C AST context. + /// \param N The number of clauses. + /// + static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned N, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPParallelDirectiveClass; + } +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h index 38c4c02..c71af38 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h @@ -18,6 +18,7 @@ #include "clang/AST/ExprObjC.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenMP.h" namespace clang { @@ -184,6 +185,41 @@ template<typename ImplClass, typename RetTy=void> class ConstStmtVisitor : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {}; +/// \brief This class implements a simple visitor for OMPClause +/// subclasses. +template<class ImplClass, template <typename> class Ptr, typename RetTy> +class OMPClauseVisitorBase { +public: +#define PTR(CLASS) typename Ptr<CLASS>::type +#define DISPATCH(CLASS) \ + return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S)) + +#define OPENMP_CLAUSE(Name, Class) \ + RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } +#include "clang/Basic/OpenMPKinds.def" + + RetTy Visit(PTR(OMPClause) S) { + // Top switch clause: visit each OMPClause. + switch (S->getClauseKind()) { + default: llvm_unreachable("Unknown clause kind!"); +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S)); +#include "clang/Basic/OpenMPKinds.def" + } + } + // Base case, ignore it. :) + RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); } +#undef PTR +#undef DISPATCH +}; + +template<class ImplClass, typename RetTy = void> +class OMPClauseVisitor : + public OMPClauseVisitorBase <ImplClass, make_ptr, RetTy> {}; +template<class ImplClass, typename RetTy = void> +class ConstOMPClauseVisitor : + public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {}; + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h index 70b934f..6c40eb1 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h @@ -60,8 +60,8 @@ public: /// The template argument is a pack expansion of a template name that was /// provided for a template template parameter. TemplateExpansion, - /// The template argument is a value- or type-dependent expression - /// stored in an Expr*. + /// The template argument is a value- or type-dependent expression or a + /// non-dependent __uuidof expression stored in an Expr*. Expression, /// The template argument is actually a parameter pack. Arguments are stored /// in the Args struct. @@ -70,57 +70,68 @@ public: private: /// \brief The kind of template argument we're storing. - unsigned Kind; struct DA { - ValueDecl *D; + unsigned Kind; bool ForRefParam; + ValueDecl *D; }; struct I { + unsigned Kind; // We store a decomposed APSInt with the data allocated by ASTContext if // BitWidth > 64. The memory may be shared between multiple // TemplateArgument instances. + unsigned BitWidth : 31; + unsigned IsUnsigned : 1; union { uint64_t VAL; ///< Used to store the <= 64 bits integer value. const uint64_t *pVal; ///< Used to store the >64 bits integer value. }; - unsigned BitWidth : 31; - unsigned IsUnsigned : 1; void *Type; }; struct A { - const TemplateArgument *Args; + unsigned Kind; unsigned NumArgs; + const TemplateArgument *Args; }; struct TA { - void *Name; + unsigned Kind; unsigned NumExpansions; + void *Name; + }; + struct TV { + unsigned Kind; + uintptr_t V; }; union { struct DA DeclArg; struct I Integer; struct A Args; struct TA TemplateArg; - uintptr_t TypeOrValue; + struct TV TypeOrValue; }; TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION; public: /// \brief Construct an empty, invalid template argument. - TemplateArgument() : Kind(Null), TypeOrValue(0) { } + TemplateArgument() { + TypeOrValue.Kind = Null; + TypeOrValue.V = 0; + } /// \brief Construct a template type argument. - TemplateArgument(QualType T, bool isNullPtr = false) - : Kind(isNullPtr ? NullPtr : Type) { - TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); + TemplateArgument(QualType T, bool isNullPtr = false) { + TypeOrValue.Kind = isNullPtr ? NullPtr : Type; + TypeOrValue.V = 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(ValueDecl *D, bool ForRefParam) : Kind(Declaration) { + TemplateArgument(ValueDecl *D, bool ForRefParam) { assert(D && "Expected decl"); + DeclArg.Kind = Declaration; DeclArg.D = D; DeclArg.ForRefParam = ForRefParam; } @@ -131,8 +142,7 @@ public: /// \brief Construct an integral constant template argument with the same /// value as Other but a different type. - TemplateArgument(const TemplateArgument &Other, QualType Type) - : Kind(Integral) { + TemplateArgument(const TemplateArgument &Other, QualType Type) { Integer = Other.Integer; Integer.Type = Type.getAsOpaquePtr(); } @@ -145,8 +155,8 @@ public: /// is taken. /// /// \param Name The template name. - TemplateArgument(TemplateName Name) : Kind(Template) - { + TemplateArgument(TemplateName Name) { + TemplateArg.Kind = Template; TemplateArg.Name = Name.getAsVoidPointer(); TemplateArg.NumExpansions = 0; } @@ -162,9 +172,8 @@ public: /// /// \param NumExpansions The number of expansions that will be generated by /// instantiating - TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) - : Kind(TemplateExpansion) - { + TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) { + TemplateArg.Kind = TemplateExpansion; TemplateArg.Name = Name.getAsVoidPointer(); if (NumExpansions) TemplateArg.NumExpansions = *NumExpansions + 1; @@ -177,15 +186,17 @@ public: /// This form of template argument only occurs in template argument /// lists used for dependent types and for expression; it will not /// occur in a non-dependent, canonical template argument list. - TemplateArgument(Expr *E) : Kind(Expression) { - TypeOrValue = reinterpret_cast<uintptr_t>(E); + TemplateArgument(Expr *E) { + TypeOrValue.Kind = Expression; + TypeOrValue.V = reinterpret_cast<uintptr_t>(E); } /// \brief Construct a template argument that is a template argument pack. /// /// We assume that storage for the template arguments provided /// outlives the TemplateArgument itself. - TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){ + TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) { + this->Args.Kind = Pack; this->Args.Args = Args; this->Args.NumArgs = NumArgs; } @@ -201,10 +212,10 @@ public: unsigned NumArgs); /// \brief Return the kind of stored template argument. - ArgKind getKind() const { return (ArgKind)Kind; } + ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; } /// \brief Determine whether this template argument has no value. - bool isNull() const { return Kind == Null; } + bool isNull() const { return getKind() == Null; } /// \brief Whether this template argument is dependent on a template /// parameter such that its result can change from one instantiation to @@ -224,40 +235,40 @@ public: /// \brief Retrieve the type for a type template argument. QualType getAsType() const { - assert(Kind == Type && "Unexpected kind"); - return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); + assert(getKind() == Type && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); } /// \brief Retrieve the declaration for a declaration non-type /// template argument. ValueDecl *getAsDecl() const { - assert(Kind == Declaration && "Unexpected kind"); + assert(getKind() == 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"); + assert(getKind() == Declaration && "Unexpected kind"); return DeclArg.ForRefParam; } /// \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)); + assert(getKind() == NullPtr && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); } /// \brief Retrieve the template name for a template name argument. TemplateName getAsTemplate() const { - assert(Kind == Template && "Unexpected kind"); + assert(getKind() == 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 { - assert((Kind == Template || Kind == TemplateExpansion) && + assert((getKind() == Template || getKind() == TemplateExpansion) && "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); @@ -270,7 +281,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"); + assert(getKind() == Integral && "Unexpected kind"); using namespace llvm; if (Integer.BitWidth <= 64) return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); @@ -282,19 +293,19 @@ public: /// \brief Retrieve the type of the integral value. QualType getIntegralType() const { - assert(Kind == Integral && "Unexpected kind"); + assert(getKind() == Integral && "Unexpected kind"); return QualType::getFromOpaquePtr(Integer.Type); } void setIntegralType(QualType T) { - assert(Kind == Integral && "Unexpected kind"); + assert(getKind() == Integral && "Unexpected kind"); Integer.Type = T.getAsOpaquePtr(); } /// \brief Retrieve the template argument as an expression. Expr *getAsExpr() const { - assert(Kind == Expression && "Unexpected kind"); - return reinterpret_cast<Expr *>(TypeOrValue); + assert(getKind() == Expression && "Unexpected kind"); + return reinterpret_cast<Expr *>(TypeOrValue.V); } /// \brief Iterator that traverses the elements of a template argument pack. @@ -303,27 +314,27 @@ public: /// \brief Iterator referencing the first argument of a template argument /// pack. pack_iterator pack_begin() const { - assert(Kind == Pack); + assert(getKind() == Pack); return Args.Args; } /// \brief Iterator referencing one past the last argument of a template /// argument pack. pack_iterator pack_end() const { - assert(Kind == Pack); + assert(getKind() == Pack); return Args.Args + Args.NumArgs; } /// \brief The number of template arguments in the given template argument /// pack. unsigned pack_size() const { - assert(Kind == Pack); + assert(getKind() == Pack); return Args.NumArgs; } /// \brief Return the array of arguments in this template argument pack. llvm::ArrayRef<TemplateArgument> getPackAsArray() const { - assert(Kind == Pack); + assert(getKind() == Pack); return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs); } @@ -494,17 +505,6 @@ public: assert(Argument.getKind() == TemplateArgument::TemplateExpansion); return LocInfo.getTemplateEllipsisLoc(); } - - /// \brief When the template argument is a pack expansion, returns - /// the pattern of the pack expansion. - /// - /// \param Ellipsis Will be set to the location of the ellipsis. - /// - /// \param NumExpansions Will be set to the number of expansions that will - /// be generated from this pack expansion, if known a priori. - TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis, - Optional<unsigned> &NumExpansions, - ASTContext &Context) const; }; /// A convenient class for passing around template argument diff --git a/contrib/llvm/tools/clang/include/clang/AST/Type.h b/contrib/llvm/tools/clang/include/clang/AST/Type.h index 04d715c..fb829e4 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Type.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Type.h @@ -441,7 +441,7 @@ public: bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } - operator bool() const { return hasQualifiers(); } + LLVM_EXPLICIT operator bool() const { return hasQualifiers(); } Qualifiers &operator+=(Qualifiers R) { addQualifiers(R); @@ -818,7 +818,7 @@ public: /// an lvalue. It removes a top-level reference (since there are no /// expressions of reference type) and deletes top-level cvr-qualifiers /// from non-class types (in C++) or all types (in C). - QualType getNonLValueExprType(ASTContext &Context) const; + QualType getNonLValueExprType(const ASTContext &Context) const; /// getDesugaredType - Return the specified type with any "sugar" removed from /// the type. This takes off typedefs, typeof's etc. If the outer level of @@ -1194,7 +1194,7 @@ private: mutable unsigned CacheValid : 1; /// \brief Linkage of this type. - mutable unsigned CachedLinkage : 2; + mutable unsigned CachedLinkage : 3; /// \brief Whether this type involves and local or unnamed types. mutable unsigned CachedLocalOrUnnamed : 1; @@ -1214,7 +1214,7 @@ private: return CachedLocalOrUnnamed; } }; - enum { NumTypeBits = 19 }; + enum { NumTypeBits = 18 }; protected: // These classes allow subclasses to somewhat cleanly pack bitfields @@ -1315,6 +1315,8 @@ protected: /// NumElements - The number of elements in the vector. unsigned NumElements : 29 - NumTypeBits; + + enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 }; }; class AttributedTypeBitfields { @@ -1454,7 +1456,7 @@ public: /// isLiteralType - Return true if this is a literal type /// (C++11 [basic.types]p10) - bool isLiteralType(ASTContext &Ctx) const; + bool isLiteralType(const ASTContext &Ctx) const; /// \brief Test if this type is a standard-layout type. /// (C++0x [basic.type]p9) @@ -1512,7 +1514,6 @@ public: bool isRealType() const; // C99 6.2.5p17 (real floating + integer) bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) bool isVoidType() const; // C99 6.2.5p19 - bool isDerivedType() const; // C99 6.2.5p20 bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) bool isAggregateType() const; bool isFundamentalType() const; @@ -1811,6 +1812,10 @@ template <> const TypedefType *Type::getAs() const; /// non-sugared type. template <> const TemplateSpecializationType *Type::getAs() const; +/// \brief This will check for an AttributedType by removing any existing sugar +/// until it reaches an AttributedType or a non-sugared type. +template <> const AttributedType *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) @@ -1991,6 +1996,44 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } }; +/// \brief Represents a pointer type decayed from an array or function type. +class DecayedType : public Type, public llvm::FoldingSetNode { + QualType OriginalType; + QualType DecayedPointer; + + DecayedType(QualType OriginalType, QualType DecayedPointer, + QualType CanonicalPtr) + : Type(Decayed, CanonicalPtr, OriginalType->isDependentType(), + OriginalType->isInstantiationDependentType(), + OriginalType->isVariablyModifiedType(), + OriginalType->containsUnexpandedParameterPack()), + OriginalType(OriginalType), DecayedPointer(DecayedPointer) { + assert(isa<PointerType>(DecayedPointer)); + } + + friend class ASTContext; // ASTContext creates these. + +public: + QualType getDecayedType() const { return DecayedPointer; } + QualType getOriginalType() const { return OriginalType; } + + QualType getPointeeType() const { + return cast<PointerType>(DecayedPointer)->getPointeeType(); + } + + bool isSugared() const { return true; } + QualType desugar() const { return DecayedPointer; } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, OriginalType); + } + static void Profile(llvm::FoldingSetNodeID &ID, QualType OriginalType) { + ID.AddPointer(OriginalType.getAsOpaquePtr()); + } + + static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } +}; + /// BlockPointerType - pointer to a block type. /// This type is to represent types syntactically represented as /// "void (^)(int)", etc. Pointee is required to always be a function type. @@ -2487,6 +2530,9 @@ public: QualType getElementType() const { return ElementType; } unsigned getNumElements() const { return VectorTypeBits.NumElements; } + static bool isVectorSizeTooLarge(unsigned NumElements) { + return NumElements > VectorTypeBitfields::MaxNumElements; + } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2641,7 +2687,11 @@ class FunctionType : public Type { // Constructor with all defaults. Use when for example creating a // function know to use defaults. - ExtInfo() : Bits(0) {} + ExtInfo() : Bits(CC_C) { } + + // Constructor with just the calling convention, which is an important part + // of the canonical type. + ExtInfo(CallingConv CC) : Bits(CC) { } bool getNoReturn() const { return Bits & NoReturnMask; } bool getProducesResult() const { return Bits & ProducesResultMask; } @@ -2784,6 +2834,12 @@ public: ExceptionSpecDecl(0), ExceptionSpecTemplate(0), ConsumedArguments(0) {} + ExtProtoInfo(CallingConv CC) + : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0), + ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0), + Exceptions(0), NoexceptExpr(0), ExceptionSpecDecl(0), + ExceptionSpecTemplate(0), ConsumedArguments(0) {} + FunctionType::ExtInfo ExtInfo; bool Variadic : 1; bool HasTrailingReturn : 1; @@ -2928,7 +2984,7 @@ public: NR_Nothrow ///< The noexcept specifier evaluates to true. }; /// \brief Get the meaning of the noexcept spec on this function, if any. - NoexceptResult getNoexceptSpec(ASTContext &Ctx) const; + NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const; unsigned getNumExceptions() const { return NumExceptions; } QualType getExceptionType(unsigned i) const { assert(i < NumExceptions && "Invalid exception number!"); @@ -2959,7 +3015,7 @@ public: return 0; return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[1]; } - bool isNothrow(ASTContext &Ctx) const { + bool isNothrow(const ASTContext &Ctx) const { ExceptionSpecificationType EST = getExceptionSpecType(); assert(EST != EST_Unevaluated && EST != EST_Uninstantiated); if (EST == EST_DynamicNone || EST == EST_BasicNoexcept) @@ -3323,9 +3379,10 @@ public: attr_objc_gc, attr_objc_ownership, attr_pcs, + attr_pcs_vfp, FirstEnumOperandKind = attr_objc_gc, - LastEnumOperandKind = attr_pcs, + LastEnumOperandKind = attr_pcs_vfp, // No operand. attr_noreturn, @@ -3337,7 +3394,11 @@ public: attr_pnaclcall, attr_inteloclbicc, attr_ms_abi, - attr_sysv_abi + attr_sysv_abi, + attr_ptr32, + attr_ptr64, + attr_sptr, + attr_uptr }; private: @@ -3367,6 +3428,10 @@ public: bool isSugared() const { return true; } QualType desugar() const { return getEquivalentType(); } + bool isMSTypeSpec() const; + + bool isCallingConv() const; + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getAttrKind(), ModifiedType, EquivalentType); } @@ -3565,10 +3630,13 @@ public: /// is no deduced type and an auto type is canonical. In the latter case, it is /// also a dependent type. class AutoType : public Type, public llvm::FoldingSetNode { - AutoType(QualType DeducedType, bool IsDecltypeAuto, bool IsDependent) + AutoType(QualType DeducedType, bool IsDecltypeAuto, + bool IsDependent) : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent, - /*VariablyModified=*/false, /*ContainsParameterPack=*/false) { + /*VariablyModified=*/false, + /*ContainsParameterPack=*/DeducedType.isNull() + ? false : DeducedType->containsUnexpandedParameterPack()) { assert((DeducedType.isNull() || !IsDependent) && "auto deduced to dependent type"); AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto; @@ -3592,7 +3660,8 @@ public: } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDeducedType(), isDecltypeAuto(), isDependentType()); + Profile(ID, getDeducedType(), isDecltypeAuto(), + isDependentType()); } static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, @@ -3656,10 +3725,6 @@ class TemplateSpecializationType public: /// \brief Determine whether any of the given template arguments are /// dependent. - static bool anyDependentTemplateArguments(const TemplateArgument *Args, - unsigned NumArgs, - bool &InstantiationDependent); - static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs, bool &InstantiationDependent); @@ -4156,8 +4221,8 @@ public: return None; } - bool isSugared() const { return false; } - QualType desugar() const { return QualType(this, 0); } + bool isSugared() const { return !Pattern->isDependentType(); } + QualType desugar() const { return isSugared() ? Pattern : QualType(this, 0); } void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPattern(), getNumExpansions()); @@ -4191,11 +4256,11 @@ public: /// /// 'C<P>' is an ObjCObjectType with base C and protocol list [P]. /// -/// 'id' is a TypedefType which is sugar for an ObjCPointerType whose +/// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose /// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType /// and no protocols. /// -/// 'id<P>' is an ObjCPointerType whose pointee is an ObjCObjecType +/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType /// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually /// this should get its own sugar class to better represent the source. class ObjCObjectType : public Type { @@ -4233,7 +4298,7 @@ public: /// getBaseType - Gets the base type of this object type. This is /// always (possibly sugar for) one of: /// - the 'id' builtin type (as opposed to the 'id' type visible to the - /// user, which is a typedef for an ObjCPointerType) + /// user, which is a typedef for an ObjCObjectPointerType) /// - the 'Class' builtin type (same caveat) /// - an ObjCObjectType (currently always an ObjCInterfaceType) QualType getBaseType() const { return BaseType; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h index 11cad9b..8ddfac7 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h @@ -6,9 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the TypeLoc interface and subclasses. -// +/// +/// \file +/// \brief Defines the clang::TypeLoc interface and its subclasses. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_TYPELOC_H @@ -34,8 +35,8 @@ namespace clang { /// \brief Base wrapper for a particular "section" of type source info. /// -/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to -/// get at the actual information. +/// A client should use the TypeLoc subclasses through castAs()/getAs() +/// in order to get at the actual information. class TypeLoc { protected: // The correctness of this relies on the property that, for Type *Ty, @@ -46,6 +47,8 @@ protected: public: /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc /// is of the desired type. + /// + /// \pre T::isKind(*this) template<typename T> T castAs() const { assert(T::isKind(*this)); @@ -90,11 +93,15 @@ public: } bool isNull() const { return !Ty; } - operator bool() const { return Ty; } + LLVM_EXPLICIT operator bool() const { return Ty; } /// \brief Returns the size of type source info data block for the given type. static unsigned getFullDataSizeForType(QualType Ty); + /// \brief Returns the alignment of type source info data block for + /// the given type. + static unsigned getLocalAlignmentForType(QualType Ty); + /// \brief Get the type for which this source info wrapper provides /// information. QualType getType() const { @@ -229,7 +236,11 @@ public: } UnqualTypeLoc getUnqualifiedLoc() const { - return UnqualTypeLoc(getTypePtr(), Data); + unsigned align = + TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0)); + uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data); + dataInt = llvm::RoundUpToAlignment(dataInt, align); + return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt)); } /// Initializes the local data of this type source info block to @@ -250,10 +261,11 @@ public: return 0; } - /// \brief Returns the size of the type source info data block. - unsigned getFullDataSize() const { - return getLocalDataSize() + - getFullDataSizeForType(getType().getLocalUnqualifiedType()); + /// \brief Returns the alignment of the type source info data block that is + /// specific to this type. + unsigned getLocalDataAlignment() const { + // We don't preserve any location information. + return 1; } private: @@ -280,9 +292,6 @@ inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { /// \tparam LocalData the structure type of local location data for /// this type /// -/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or -/// else the world will end. -/// /// TypeLocs with non-constant amounts of local data should override /// getExtraLocalDataSize(); getExtraLocalData() will then point to /// this extra memory. @@ -309,7 +318,8 @@ class ConcreteTypeLoc : public Base { friend class TypeLoc; static bool isKind(const TypeLoc &TL) { - return Derived::classofType(TL.getTypePtr()); + return !TL.getType().hasLocalQualifiers() && + Derived::classofType(TL.getTypePtr()); } static bool classofType(const Type *Ty) { @@ -317,12 +327,16 @@ class ConcreteTypeLoc : public Base { } public: - unsigned getLocalDataSize() const { - return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); + unsigned getLocalDataAlignment() const { + return std::max(llvm::alignOf<LocalData>(), + asDerived()->getExtraLocalDataAlignment()); } - // Give a default implementation that's useful for leaf types. - unsigned getFullDataSize() const { - return asDerived()->getLocalDataSize() + getInnerTypeSize(); + unsigned getLocalDataSize() const { + unsigned size = sizeof(LocalData); + unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); + size = llvm::RoundUpToAlignment(size, extraAlign); + size += asDerived()->getExtraLocalDataSize(); + return size; } TypeLoc getNextTypeLoc() const { @@ -338,6 +352,10 @@ protected: return 0; } + unsigned getExtraLocalDataAlignment() const { + return 1; + } + LocalData *getLocalData() const { return static_cast<LocalData*>(Base::Data); } @@ -346,11 +364,17 @@ protected: /// local data that can't be captured in the Info (e.g. because it's /// of variable size). void *getExtraLocalData() const { - return getLocalData() + 1; + unsigned size = sizeof(LocalData); + unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); + size = llvm::RoundUpToAlignment(size, extraAlign); + return reinterpret_cast<char*>(Base::Data) + size; } void *getNonLocalData() const { - return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize(); + uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data); + data += asDerived()->getLocalDataSize(); + data = llvm::RoundUpToAlignment(data, getNextTypeAlign()); + return reinterpret_cast<void*>(data); } struct HasNoInnerType {}; @@ -373,6 +397,18 @@ private: return getInnerTypeLoc().getFullDataSize(); } + unsigned getNextTypeAlign() const { + return getNextTypeAlign(asDerived()->getInnerType()); + } + + unsigned getNextTypeAlign(HasNoInnerType _) const { + return 1; + } + + unsigned getNextTypeAlign(QualType T) const { + return TypeLoc::getLocalAlignmentForType(T); + } + TypeLoc getNextTypeLoc(HasNoInnerType _) const { return TypeLoc(); } @@ -393,7 +429,8 @@ class InheritingConcreteTypeLoc : public Base { } static bool isKind(const TypeLoc &TL) { - return Derived::classofType(TL.getTypePtr()); + return !TL.getType().hasLocalQualifiers() && + Derived::classofType(TL.getTypePtr()); } static bool isKind(const UnqualTypeLoc &TL) { return Derived::classofType(TL.getTypePtr()); @@ -417,7 +454,8 @@ class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Type, TypeSpecLocInfo> { public: - enum { LocalDataSize = sizeof(TypeSpecLocInfo) }; + enum { LocalDataSize = sizeof(TypeSpecLocInfo), + LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment }; SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; @@ -448,8 +486,6 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, BuiltinType, BuiltinLocInfo> { public: - enum { LocalDataSize = sizeof(BuiltinLocInfo) }; - SourceLocation getBuiltinLoc() const { return getLocalData()->BuiltinLoc; } @@ -478,6 +514,10 @@ public: return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; } + unsigned getExtraLocalDataAlignment() const { + return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1; + } + SourceRange getLocalSourceRange() const { return SourceRange(getBuiltinLoc(), getBuiltinLoc()); } @@ -840,6 +880,10 @@ public: return this->getNumProtocols() * sizeof(SourceLocation); } + unsigned getExtraLocalDataAlignment() const { + return llvm::alignOf<SourceLocation>(); + } + QualType getInnerType() const { return getTypePtr()->getBaseType(); } @@ -933,6 +977,40 @@ inline TypeLoc TypeLoc::IgnoreParens() const { return *this; } + +struct DecayedLocInfo { }; // Nothing. + +/// \brief Wrapper for source info for pointers decayed from arrays and +/// functions. +class DecayedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, DecayedTypeLoc, + DecayedType, DecayedLocInfo> { +public: + TypeLoc getOriginalLoc() const { + return getInnerTypeLoc(); + } + + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + // do nothing + } + + QualType getInnerType() const { + // The inner type is the undecayed type, since that's what we have source + // location information for. + return getTypePtr()->getOriginalType(); + } + + SourceRange getLocalSourceRange() const { + return SourceRange(); + } + + unsigned getLocalDataSize() const { + // sizeof(DecayedLocInfo) is 1, but we don't need its address to be unique + // anyway. TypeLocBuilder can't handle data sizes of 1. + return 0; // No data. + } +}; + + struct PointerLikeLocInfo { SourceLocation StarLoc; }; @@ -1166,6 +1244,10 @@ public: return getNumArgs() * sizeof(ParmVarDecl*); } + unsigned getExtraLocalDataAlignment() const { + return llvm::alignOf<ParmVarDecl*>(); + } + QualType getInnerType() const { return getTypePtr()->getResultType(); } }; @@ -1357,6 +1439,10 @@ public: return getNumArgs() * sizeof(TemplateArgumentLocInfo); } + unsigned getExtraLocalDataAlignment() const { + return llvm::alignOf<TemplateArgumentLocInfo>(); + } + private: TemplateArgumentLocInfo *getArgInfos() const { return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); @@ -1761,6 +1847,10 @@ public: return getNumArgs() * sizeof(TemplateArgumentLocInfo); } + unsigned getExtraLocalDataAlignment() const { + return llvm::alignOf<TemplateArgumentLocInfo>(); + } + private: TemplateArgumentLocInfo *getArgInfos() const { return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def b/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def index 840e07d..3126f48 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeNodes.def @@ -81,6 +81,7 @@ TYPE(FunctionNoProto, FunctionType) DEPENDENT_TYPE(UnresolvedUsing, Type) NON_CANONICAL_TYPE(Paren, Type) NON_CANONICAL_TYPE(Typedef, Type) +NON_CANONICAL_TYPE(Decayed, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type) @@ -98,7 +99,7 @@ TYPE(Auto, Type) DEPENDENT_TYPE(InjectedClassName, Type) DEPENDENT_TYPE(DependentName, Type) DEPENDENT_TYPE(DependentTemplateSpecialization, Type) -DEPENDENT_TYPE(PackExpansion, Type) +NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type) TYPE(ObjCObject, Type) TYPE(ObjCInterface, ObjCObjectType) TYPE(ObjCObjectPointer, Type) diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h b/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h index 59b59f5..9c9f15e 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeOrdering.h @@ -6,11 +6,14 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file provides a function objects and specializations that -// allow QualType values to be sorted, used in std::maps, std::sets, -// llvm::DenseMaps, and llvm::DenseSets. -// +/// +/// \file +/// \brief Allows QualTypes to be sorted and hence used in maps and sets. +/// +/// Defines clang::QualTypeOrdering, a total ordering on clang::QualType, +/// and hence enables QualType values to be sorted and to be used in +/// std::maps, std::sets, llvm::DenseMaps, and llvm::DenseSets. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TYPE_ORDERING_H @@ -22,8 +25,7 @@ namespace clang { -/// QualTypeOrdering - Function object that provides a total ordering -/// on QualType values. +/// \brief Function object that provides a total ordering on QualType values. struct QualTypeOrdering : std::binary_function<QualType, QualType, bool> { bool operator()(QualType T1, QualType T2) const { return std::less<void*>()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr()); diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h index 242aa58..11e5a47 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeVisitor.h @@ -22,9 +22,50 @@ namespace clang { return static_cast<ImplClass*>(this)-> \ Visit##CLASS(static_cast<const CLASS*>(T)) +/// \brief An operation on a type. +/// +/// \tparam ImplClass Class implementing the operation. Must be inherited from +/// TypeVisitor. +/// \tparam RetTy %Type of result produced by the operation. +/// +/// The class implements polymorphic operation on an object of type derived +/// from Type. The operation is performed by calling method Visit. It then +/// dispatches the call to function \c VisitFooType, if actual argument type +/// is \c FooType. +/// +/// The class implements static polymorphism using Curiously Recurring +/// Template Pattern. It is designed to be a base class for some concrete +/// class: +/// +/// \code +/// class SomeVisitor : public TypeVisitor<SomeVisitor,sometype> { ... }; +/// ... +/// Type *atype = ... +/// ... +/// SomeVisitor avisitor; +/// sometype result = avisitor.Visit(atype); +/// \endcode +/// +/// Actual treatment is made by methods of the derived class, TypeVisitor only +/// dispatches call to the appropriate method. If the implementation class +/// \c ImplClass provides specific action for some type, say +/// \c ConstantArrayType, it should define method +/// <tt>VisitConstantArrayType(const ConstantArrayType*)</tt>. Otherwise +/// \c TypeVisitor dispatches call to the method that handles parent type. In +/// this example handlers are tried in the sequence: +/// +/// \li <tt>ImplClass::VisitConstantArrayType(const ConstantArrayType*)</tt> +/// \li <tt>ImplClass::VisitArrayType(const ArrayType*)</tt> +/// \li <tt>ImplClass::VisitType(const Type*)</tt> +/// \li <tt>TypeVisitor::VisitType(const Type*)</tt> +/// +/// The first function of this sequence that is defined will handle object of +/// type \c ConstantArrayType. template<typename ImplClass, typename RetTy=void> class TypeVisitor { public: + + /// \brief Performs the operation associated with this visitor object. RetTy Visit(const Type *T) { // Top switch stmt: dispatch to VisitFooType for each FooType. switch (T->getTypeClass()) { @@ -42,7 +83,8 @@ public: } #include "clang/AST/TypeNodes.def" - // Base case, ignore it. :) + /// \brief Method called if \c ImpClass doesn't provide specific handler + /// for some type class. RetTy VisitType(const Type*) { return RetTy(); } }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h index d26065e..759af25 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h +++ b/contrib/llvm/tools/clang/include/clang/AST/UnresolvedSet.h @@ -51,6 +51,7 @@ public: typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category; NamedDecl *getDecl() const { return ir->getDecl(); } + void setDecl(NamedDecl *ND) const { return ir->setDecl(ND); } AccessSpecifier getAccess() const { return ir->getAccess(); } void setAccess(AccessSpecifier AS) { ir->setAccess(AS); } DeclAccessPair getPair() const { return *ir; } @@ -88,7 +89,7 @@ public: bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } }; -/// UnresolvedSet - A set of unresolved declarations. +/// \brief A set of unresolved declarations. class UnresolvedSetImpl { typedef SmallVectorImpl<DeclAccessPair> DeclsTy; @@ -139,15 +140,9 @@ public: I.ir->set(New, AS); } - void erase(unsigned I) { - decls()[I] = decls().back(); - decls().pop_back(); - } + void erase(unsigned I) { decls()[I] = decls().pop_back_val(); } - void erase(iterator I) { - *I.ir = decls().back(); - decls().pop_back(); - } + void erase(iterator I) { *I.ir = decls().pop_back_val(); } void setAccess(iterator I, AccessSpecifier AS) { I.ir->setAccess(AS); @@ -177,7 +172,7 @@ private: } }; -/// A set of unresolved declarations +/// \brief A set of unresolved declarations. template <unsigned InlineCapacity> class UnresolvedSet : public UnresolvedSetImpl { SmallVector<DeclAccessPair, InlineCapacity> Decls; diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h index f24bb3f..727bf51 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/AST/VTTBuilder.h @@ -63,54 +63,50 @@ struct VTTComponent { : VTableIndex(VTableIndex), VTableBase(VTableBase) {} }; -/// VTT builder - Class for building VTT layout information. +/// \brief Class for building VTT layout information. class VTTBuilder { ASTContext &Ctx; - /// MostDerivedClass - The most derived class for which we're building this - /// vtable. + /// \brief The most derived class for which we're building this vtable. const CXXRecordDecl *MostDerivedClass; typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy; - /// VTTVTables - The VTT vtables. + /// \brief The VTT vtables. VTTVTablesVectorTy VTTVTables; typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy; - /// VTTComponents - The VTT components. + /// \brief The VTT components. VTTComponentsVectorTy VTTComponents; - /// MostDerivedClassLayout - the AST record layout of the most derived class. + /// \brief The AST record layout of the most derived class. const ASTRecordLayout &MostDerivedClassLayout; typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; - /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived - /// class. + /// \brief The sub-VTT indices for the bases of the most derived class. llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies; - /// SecondaryVirtualPointerIndices - The secondary virtual pointer indices of - /// all subobjects of the most derived class. + /// \brief The secondary virtual pointer indices of all subobjects of + /// the most derived class. llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices; - /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for - /// the VTT. + /// \brief Whether the VTT builder should generate LLVM IR for the VTT. bool GenerateDefinition; - /// AddVTablePointer - Add a vtable pointer to the VTT currently being built. + /// \brief Add a vtable pointer to the VTT currently being built. void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, const CXXRecordDecl *VTableClass); - /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base - /// subobject. + /// \brief Lay out the secondary VTTs of the given base subobject. void LayoutSecondaryVTTs(BaseSubobject Base); - /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers - /// for the given base subobject. + /// \brief Lay out the secondary virtual pointers for the given base + /// subobject. /// /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base /// or a direct or indirect base of a virtual base. @@ -120,17 +116,17 @@ class VTTBuilder { const CXXRecordDecl *VTableClass, VisitedVirtualBasesSetTy &VBases); - /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers - /// for the given base subobject. + /// \brief Lay out the secondary virtual pointers for the given base + /// subobject. void LayoutSecondaryVirtualPointers(BaseSubobject Base, uint64_t VTableIndex); - /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the - /// given record decl. + /// \brief Lay out the VTTs for the virtual base classes of the given + /// record declaration. void LayoutVirtualVTTs(const CXXRecordDecl *RD, VisitedVirtualBasesSetTy &VBases); - /// LayoutVTT - Will lay out the VTT for the given subobject, including any + /// \brief Lay out the VTT for the given subobject, including any /// secondary VTTs, secondary virtual pointers and virtual VTTs. void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual); @@ -138,23 +134,22 @@ public: VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass, bool GenerateDefinition); - // getVTTComponents - Returns a reference to the VTT components. + // \brief Returns a reference to the VTT components. const VTTComponentsVectorTy &getVTTComponents() const { return VTTComponents; } - // getVTTVTables - Returns a reference to the VTT vtables. + // \brief Returns a reference to the VTT vtables. const VTTVTablesVectorTy &getVTTVTables() const { return VTTVTables; } - /// getSubVTTIndicies - Returns a reference to the sub-VTT indices. + /// \brief Returns a reference to the sub-VTT indices. const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const { return SubVTTIndicies; } - /// getSecondaryVirtualPointerIndices - Returns a reference to the secondary - /// virtual pointer indices. + /// \brief Returns a reference to the secondary virtual pointer indices. const llvm::DenseMap<BaseSubobject, uint64_t> & getSecondaryVirtualPointerIndices() const { return SecondaryVirtualPointerIndices; diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h index bcbe875..4e45132 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h @@ -20,12 +20,13 @@ #include "clang/AST/RecordLayout.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/SetVector.h" +#include "llvm/ADT/DenseSet.h" #include <utility> namespace clang { class CXXRecordDecl; -/// VTableComponent - Represents a single component in a vtable. +/// \brief Represents a single component in a vtable. class VTableComponent { public: enum Kind { @@ -35,15 +36,17 @@ public: CK_RTTI, CK_FunctionPointer, - /// CK_CompleteDtorPointer - A pointer to the complete destructor. + /// \brief A pointer to the complete destructor. CK_CompleteDtorPointer, - /// CK_DeletingDtorPointer - A pointer to the deleting destructor. + /// \brief A pointer to the deleting destructor. CK_DeletingDtorPointer, - /// CK_UnusedFunctionPointer - In some cases, a vtable function pointer - /// will end up never being called. Such vtable function pointers are - /// represented as a CK_UnusedFunctionPointer. + /// \brief An entry that is never used. + /// + /// In some cases, a vtable function pointer will end up never being + /// called. Such vtable function pointers are represented as a + /// CK_UnusedFunctionPointer. CK_UnusedFunctionPointer }; @@ -94,7 +97,7 @@ public: return VTableComponent(I); } - /// getKind - Get the kind of this vtable component. + /// \brief Get the kind of this vtable component. Kind getKind() const { return (Kind)(Value & 0x7); } @@ -189,7 +192,7 @@ private: /// The kind is stored in the lower 3 bits of the value. For offsets, we /// make use of the facts that classes can't be larger than 2^55 bytes, - /// so we store the offset in the lower part of the 61 bytes that remain. + /// so we store the offset in the lower part of the 61 bits that remain. /// (The reason that we're not simply using a PointerIntPair here is that we /// need the offsets to be 64-bit, even when on a 32-bit machine). int64_t Value; @@ -198,7 +201,6 @@ private: class VTableLayout { public: typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy; - typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; typedef const VTableComponent *vtable_component_iterator; typedef const VTableThunkTy *vtable_thunk_iterator; @@ -208,11 +210,11 @@ private: uint64_t NumVTableComponents; llvm::OwningArrayPtr<VTableComponent> VTableComponents; - /// VTableThunks - Contains thunks needed by vtables. + /// \brief Contains thunks needed by vtables, sorted by indices. uint64_t NumVTableThunks; llvm::OwningArrayPtr<VTableThunkTy> VTableThunks; - /// Address points - Address points for all vtables. + /// \brief Address points for all vtables. AddressPointsMapTy AddressPoints; bool IsMicrosoftABI; @@ -231,23 +233,21 @@ public: } vtable_component_iterator vtable_component_begin() const { - return VTableComponents.get(); + return VTableComponents.get(); } vtable_component_iterator vtable_component_end() const { - return VTableComponents.get()+NumVTableComponents; + return VTableComponents.get() + NumVTableComponents; } - uint64_t getNumVTableThunks() const { - return NumVTableThunks; - } + uint64_t getNumVTableThunks() const { return NumVTableThunks; } vtable_thunk_iterator vtable_thunk_begin() const { - return VTableThunks.get(); + return VTableThunks.get(); } vtable_thunk_iterator vtable_thunk_end() const { - return VTableThunks.get()+NumVTableThunks; + return VTableThunks.get() + NumVTableThunks; } uint64_t getAddressPoint(BaseSubobject Base) const { @@ -266,19 +266,45 @@ public: } }; -class VTableContext { - ASTContext &Context; - +class VTableContextBase { public: - typedef SmallVector<std::pair<uint64_t, ThunkInfo>, 1> - VTableThunksTy; typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; +protected: + typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; + + /// \brief Contains all thunks that a given method decl will need. + ThunksMapTy Thunks; + + /// Compute and store all vtable related information (vtable layout, vbase + /// offset offsets, thunks etc) for the given record decl. + virtual void computeVTableRelatedInformation(const CXXRecordDecl *RD) = 0; + + virtual ~VTableContextBase() {} + +public: + virtual const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) { + const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()->getCanonicalDecl()); + computeVTableRelatedInformation(MD->getParent()); + + // This assumes that all the destructors present in the vtable + // use exactly the same set of thunks. + ThunksMapTy::const_iterator I = Thunks.find(MD); + if (I == Thunks.end()) { + // We did not find a thunk for this method. + return 0; + } + + return &I->second; + } +}; + +class ItaniumVTableContext : public VTableContextBase { private: bool IsMicrosoftABI; - /// MethodVTableIndices - Contains the index (relative to the vtable address - /// point) where the function pointer for a virtual function is stored. + /// \brief Contains the index (relative to the vtable address point) + /// where the function pointer for a virtual function is stored. typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy; MethodVTableIndicesTy MethodVTableIndices; @@ -286,49 +312,25 @@ private: VTableLayoutMapTy; VTableLayoutMapTy VTableLayouts; - /// NumVirtualFunctionPointers - Contains the number of virtual function - /// pointers in the vtable for a given record decl. - llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers; - typedef std::pair<const CXXRecordDecl *, const CXXRecordDecl *> ClassPairTy; - /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to - /// the address point) in chars where the offsets for virtual bases of a class - /// are stored. + /// \brief vtable offsets for offsets of virtual bases of a class. + /// + /// Contains the vtable offset (relative to the address point) in chars + /// where the offsets for virtual bases of a class are stored. typedef llvm::DenseMap<ClassPairTy, CharUnits> VirtualBaseClassOffsetOffsetsMapTy; VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets; - typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; - - /// Thunks - Contains all thunks that a given method decl will need. - ThunksMapTy Thunks; - - void ComputeMethodVTableIndices(const CXXRecordDecl *RD); - - /// ComputeVTableRelatedInformation - Compute and store all vtable related - /// information (vtable layout, vbase offset offsets, thunks etc) for the - /// given record decl. - void ComputeVTableRelatedInformation(const CXXRecordDecl *RD); - - /// ErrorUnsupported - Print out an error that the v-table layout code - /// doesn't support the particular C++ feature yet. - void ErrorUnsupported(StringRef Feature, SourceLocation Location); + void computeVTableRelatedInformation(const CXXRecordDecl *RD); public: - VTableContext(ASTContext &Context); - ~VTableContext(); - - bool isMicrosoftABI() const { - // FIXME: Currently, this method is only used in the VTableContext and - // VTableBuilder code which is ABI-specific. Probably we can remove it - // when we add a layer of abstraction for vtable generation. - return IsMicrosoftABI; - } + ItaniumVTableContext(ASTContext &Context); + ~ItaniumVTableContext(); const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) { - ComputeVTableRelatedInformation(RD); + computeVTableRelatedInformation(RD); assert(VTableLayouts.count(RD) && "No layout for this record decl!"); return *VTableLayouts[RD]; @@ -340,36 +342,177 @@ public: bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass); - const ThunkInfoVectorTy *getThunkInfo(const CXXMethodDecl *MD) { - ComputeVTableRelatedInformation(MD->getParent()); + /// \brief Locate a virtual function in the vtable. + /// + /// Return the index (relative to the vtable address point) where the + /// function pointer for the given virtual function is stored. + uint64_t getMethodVTableIndex(GlobalDecl GD); - ThunksMapTy::const_iterator I = Thunks.find(MD); - if (I == Thunks.end()) { - // We did not find a thunk for this method. - return 0; - } + /// Return the offset in chars (relative to the vtable address point) where + /// the offset of the virtual base that contains the given base is stored, + /// otherwise, if no virtual base contains the given class, return 0. + /// + /// Base must be a virtual base class or an unambiguous base. + CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, + const CXXRecordDecl *VBase); +}; - return &I->second; +struct VFPtrInfo { + typedef SmallVector<const CXXRecordDecl *, 1> BasePath; + + // Don't pass the PathToMangle as it should be calculated later. + VFPtrInfo(CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr) + : VBTableIndex(0), LastVBase(0), VFPtrOffset(VFPtrOffset), + PathToBaseWithVFPtr(PathToBaseWithVFPtr), VFPtrFullOffset(VFPtrOffset) { } - /// getNumVirtualFunctionPointers - Return the number of virtual function - /// pointers in the vtable for a given record decl. - uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD); + // Don't pass the PathToMangle as it should be calculated later. + VFPtrInfo(uint64_t VBTableIndex, const CXXRecordDecl *LastVBase, + CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr, + CharUnits VFPtrFullOffset) + : VBTableIndex(VBTableIndex), LastVBase(LastVBase), + VFPtrOffset(VFPtrOffset), PathToBaseWithVFPtr(PathToBaseWithVFPtr), + VFPtrFullOffset(VFPtrFullOffset) { + assert(VBTableIndex && "The full constructor should only be used " + "for vfptrs in virtual bases"); + assert(LastVBase); + } - /// getMethodVTableIndex - Return the index (relative to the vtable address - /// point) where the function pointer for the given virtual function is - /// stored. - uint64_t getMethodVTableIndex(GlobalDecl GD); + /// If nonzero, holds the vbtable index of the virtual base with the vfptr. + uint64_t VBTableIndex; - /// getVirtualBaseOffsetOffset - Return the offset in chars (relative to the - /// vtable address point) where the offset of the virtual base that contains - /// the given base is stored, otherwise, if no virtual base contains the given - /// class, return 0. Base must be a virtual base class or an unambigious - /// base. - CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, - const CXXRecordDecl *VBase); + /// Stores the last vbase on the path from the complete type to the vfptr. + const CXXRecordDecl *LastVBase; + + /// This is the offset of the vfptr from the start of the last vbase, + /// or the complete type if there are no virtual bases. + CharUnits VFPtrOffset; + + /// This holds the base classes path from the complete type to the first base + /// with the given vfptr offset, in the base-to-derived order. + BasePath PathToBaseWithVFPtr; + + /// This holds the subset of records that need to be mangled into the vftable + /// symbol name in order to get a unique name, in the derived-to-base order. + BasePath PathToMangle; + + /// This is the full offset of the vfptr from the start of the complete type. + CharUnits VFPtrFullOffset; }; +class MicrosoftVTableContext : public VTableContextBase { +public: + struct MethodVFTableLocation { + /// If nonzero, holds the vbtable index of the virtual base with the vfptr. + uint64_t VBTableIndex; + + /// If nonnull, holds the last vbase which contains the vfptr that the + /// method definition is adjusted to. + const CXXRecordDecl *VBase; + + /// This is the offset of the vfptr from the start of the last vbase, or the + /// complete type if there are no virtual bases. + CharUnits VFPtrOffset; + + /// Method's index in the vftable. + uint64_t Index; + + MethodVFTableLocation() + : VBTableIndex(0), VBase(0), VFPtrOffset(CharUnits::Zero()), + Index(0) {} + + MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase, + CharUnits VFPtrOffset, uint64_t Index) + : VBTableIndex(VBTableIndex), VBase(VBase), + VFPtrOffset(VFPtrOffset), Index(Index) {} + + bool operator<(const MethodVFTableLocation &other) const { + if (VBTableIndex != other.VBTableIndex) { + assert(VBase != other.VBase); + return VBTableIndex < other.VBTableIndex; + } + if (VFPtrOffset != other.VFPtrOffset) + return VFPtrOffset < other.VFPtrOffset; + if (Index != other.Index) + return Index < other.Index; + return false; + } + }; + + typedef SmallVector<VFPtrInfo, 1> VFPtrListTy; + +private: + ASTContext &Context; + + typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation> + MethodVFTableLocationsTy; + MethodVFTableLocationsTy MethodVFTableLocations; + + typedef llvm::DenseMap<const CXXRecordDecl *, VFPtrListTy> + VFPtrLocationsMapTy; + VFPtrLocationsMapTy VFPtrLocations; + + typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy; + typedef llvm::DenseMap<VFTableIdTy, const VTableLayout *> VFTableLayoutMapTy; + VFTableLayoutMapTy VFTableLayouts; + + typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> BasesSetVectorTy; + void enumerateVFPtrs(const CXXRecordDecl *MostDerivedClass, + const ASTRecordLayout &MostDerivedClassLayout, + BaseSubobject Base, const CXXRecordDecl *LastVBase, + const VFPtrInfo::BasePath &PathFromCompleteClass, + BasesSetVectorTy &VisitedVBases, + MicrosoftVTableContext::VFPtrListTy &Result); + + void enumerateVFPtrs(const CXXRecordDecl *ForClass, + MicrosoftVTableContext::VFPtrListTy &Result); + + void computeVTableRelatedInformation(const CXXRecordDecl *RD); + + void dumpMethodLocations(const CXXRecordDecl *RD, + const MethodVFTableLocationsTy &NewMethods, + raw_ostream &); + + typedef std::pair<const CXXRecordDecl *, const CXXRecordDecl *> ClassPairTy; + typedef llvm::DenseMap<ClassPairTy, unsigned> VBTableIndicesTy; + VBTableIndicesTy VBTableIndices; + llvm::DenseSet<const CXXRecordDecl *> ComputedVBTableIndices; + + void computeVBTableRelatedInformation(const CXXRecordDecl *RD); + +public: + MicrosoftVTableContext(ASTContext &Context) : Context(Context) {} + + ~MicrosoftVTableContext() { llvm::DeleteContainerSeconds(VFTableLayouts); } + + const VFPtrListTy &getVFPtrOffsets(const CXXRecordDecl *RD); + + const VTableLayout &getVFTableLayout(const CXXRecordDecl *RD, + CharUnits VFPtrOffset); + + const MethodVFTableLocation &getMethodVFTableLocation(GlobalDecl GD); + + const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) { + // Complete destructors don't have a slot in a vftable, so no thunks needed. + if (isa<CXXDestructorDecl>(GD.getDecl()) && + GD.getDtorType() == Dtor_Complete) + return 0; + return VTableContextBase::getThunkInfo(GD); + } + + /// \brief Returns the index of VBase in the vbtable of Derived. + /// VBase must be a morally virtual base of Derived. + /// The vbtable is an array of i32 offsets. The first entry is a self entry, + /// and the rest are offsets from the vbptr to virtual bases. + unsigned getVBTableIndex(const CXXRecordDecl *Derived, + const CXXRecordDecl *VBase) { + computeVBTableRelatedInformation(Derived); + ClassPairTy Pair(Derived, VBase); + assert(VBTableIndices.count(Pair) == 1 && + "VBase must be a vbase of Derived"); + return VBTableIndices[Pair]; + } +}; } #endif diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h index 870a39b..db0a83d 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h @@ -97,6 +97,11 @@ public: /// /// Optionally override to do per translation unit tasks. virtual void onStartOfTranslationUnit() {} + + /// \brief Called at the end of each translation unit. + /// + /// Optionally override to do per translation unit tasks. + virtual void onEndOfTranslationUnit() {} }; /// \brief Called when parsing is finished. Intended for testing only. @@ -131,6 +136,17 @@ public: MatchCallback *Action); /// @} + /// \brief Adds a matcher to execute when running over the AST. + /// + /// This is similar to \c addMatcher(), but it uses the dynamic interface. It + /// is more flexible, but the lost type information enables a caller to pass + /// a matcher that cannot match anything. + /// + /// \returns \c true if the matcher is a valid top-level matcher, \c false + /// otherwise. + bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, + MatchCallback *Action); + /// \brief Creates a clang ASTConsumer that finds all matches. clang::ASTConsumer *newASTConsumer(); @@ -147,6 +163,9 @@ public: ASTContext &Context); /// @} + /// \brief Finds all matches in the given AST. + void matchAST(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 @@ -157,7 +176,7 @@ public: private: /// \brief For each \c DynTypedMatcher a \c MatchCallback that will be called /// when it matches. - std::vector<std::pair<const internal::DynTypedMatcher*, MatchCallback*> > + std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > MatcherCallbackPairs; /// \brief Called when parsing is done. diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h index ab62dd0..0a3157d 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -45,6 +45,7 @@ #ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H +#include "clang/AST/DeclFriend.h" #include "clang/AST/DeclTemplate.h" #include "clang/ASTMatchers/ASTMatchersInternal.h" #include "clang/ASTMatchers/ASTMatchersMacros.h" @@ -85,6 +86,16 @@ public: } /// @} + /// \brief Type of mapping from binding identifiers to bound nodes. This type + /// is an associative container with a key type of \c std::string and a value + /// type of \c clang::ast_type_traits::DynTypedNode + typedef internal::BoundNodesMap::IDToNodeMap IDToNodeMap; + + /// \brief Retrieve mapping from binding identifiers to bound nodes. + const IDToNodeMap &getMap() const { + return MyBoundNodes.getMap(); + } + private: /// \brief Create BoundNodes from a pre-filled map of bindings. BoundNodes(internal::BoundNodesMap &MyBoundNodes) @@ -92,7 +103,7 @@ private: internal::BoundNodesMap MyBoundNodes; - friend class internal::BoundNodesTree; + friend class internal::BoundNodesTreeBuilder; }; /// \brief If the provided matcher matches a node, binds the node to \c ID. @@ -204,6 +215,28 @@ const internal::VariadicDynCastAllOfMatcher< Decl, ClassTemplateSpecializationDecl> classTemplateSpecializationDecl; +/// \brief Matches declarator declarations (field, variable, function +/// and non-type template parameter declarations). +/// +/// Given +/// \code +/// class X { int y; }; +/// \endcode +/// declaratorDecl() +/// matches \c int y. +const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl> + declaratorDecl; + +/// \brief Matches parameter variable declarations. +/// +/// Given +/// \code +/// void f(int x); +/// \endcode +/// parmVarDecl() +/// matches \c int x. +const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl; + /// \brief Matches C++ access specifier declarations. /// /// Given @@ -219,6 +252,17 @@ const internal::VariadicDynCastAllOfMatcher< Decl, AccessSpecDecl> accessSpecDecl; +/// \brief Matches constructor initializers. +/// +/// Examples matches \c i(42). +/// \code +/// class C { +/// C() : i(42) {} +/// int i; +/// }; +/// \endcode +const internal::VariadicAllOfMatcher<CXXCtorInitializer> ctorInitializer; + /// \brief Matches public C++ declarations. /// /// Given @@ -281,12 +325,9 @@ AST_MATCHER(Decl, isPrivate) { /// matches the specialization \c A<int> AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument, internal::Matcher<TemplateArgument>, InnerMatcher) { - const TemplateArgumentList &List = Node.getTemplateArgs(); - for (unsigned i = 0; i < List.size(); ++i) { - if (InnerMatcher.matches(List.get(i), Finder, Builder)) - return true; - } - return false; + llvm::ArrayRef<TemplateArgument> List = Node.getTemplateArgs().asArray(); + return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder, + Builder); } /// \brief Matches expressions that match InnerMatcher after any implicit casts @@ -520,6 +561,16 @@ const internal::VariadicDynCastAllOfMatcher< Decl, FunctionTemplateDecl> functionTemplateDecl; +/// \brief Matches friend declarations. +/// +/// Given +/// \code +/// class X { friend void foo(); }; +/// \endcode +/// friendDecl() +/// matches 'friend void foo()'. +const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl; + /// \brief Matches statements. /// /// Given @@ -607,6 +658,21 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr; /// matches \code using X::x \endcode const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl; +/// \brief Matches unresolved using value declarations. +/// +/// Given +/// \code +/// template<typename X> +/// class C : private X { +/// using X::x; +/// }; +/// \endcode +/// unresolvedUsingValueDecl() +/// matches \code using X::x \endcode +const internal::VariadicDynCastAllOfMatcher< + Decl, + UnresolvedUsingValueDecl> unresolvedUsingValueDecl; + /// \brief Matches constructor call expressions (including implicit ones). /// /// Example matches string(ptr, n) and ptr within arguments of f @@ -621,6 +687,18 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CXXConstructExpr> constructExpr; +/// \brief Matches unresolved constructor call expressions. +/// +/// Example matches T(t) in return statement of f +/// (matcher = unresolvedConstructExpr()) +/// \code +/// template <typename T> +/// void f(const T& t) { return T(t); } +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CXXUnresolvedConstructExpr> unresolvedConstructExpr; + /// \brief Matches implicit and explicit this expressions. /// /// Example matches the implicit this expression in "return i". @@ -894,6 +972,26 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt; /// matches 'case 42: break;' and 'default: break;'. const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase; +/// \brief Matches case statements inside switch statements. +/// +/// Given +/// \code +/// switch(a) { case 42: break; default: break; } +/// \endcode +/// caseStmt() +/// matches 'case 42: break;'. +const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt; + +/// \brief Matches default statements inside switch statements. +/// +/// Given +/// \code +/// switch(a) { case 42: break; default: break; } +/// \endcode +/// defaultStmt() +/// matches 'default: break;'. +const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt; + /// \brief Matches compound statements. /// /// Example matches '{}' and '{{}}'in 'for (;;) {{}}' @@ -981,15 +1079,25 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CharacterLiteral> characterLiteral; -/// \brief Matches integer literals of all sizes / encodings. -/// -/// Not matching character-encoded integers such as L'a'. +/// \brief Matches integer literals of all sizes / encodings, e.g. +/// 1, 1L, 0x1 and 1U. /// -/// Example matches 1, 1L, 0x1, 1U +/// Does not match character-encoded integers such as L'a'. const internal::VariadicDynCastAllOfMatcher< Stmt, IntegerLiteral> integerLiteral; +/// \brief Matches float literals of all sizes / encodings, e.g. +/// 1.0, 1.0f, 1.0L and 1e10. +/// +/// Does not match implicit conversions such as +/// \code +/// float a = 10; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + FloatingLiteral> floatLiteral; + /// \brief Matches user defined literal operator call. /// /// Example match: "foo"_suffix @@ -1171,6 +1279,16 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CXXFunctionalCastExpr> functionalCastExpr; +/// \brief Matches functional cast expressions having N != 1 arguments +/// +/// Example: Matches Foo(bar, bar) +/// \code +/// Foo h = Foo(bar, bar); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CXXTemporaryObjectExpr> temporaryObjectExpr; + /// \brief Matches \c QualTypes in the clang AST. const internal::VariadicAllOfMatcher<QualType> qualType; @@ -1199,93 +1317,23 @@ const internal::VariadicAllOfMatcher<TypeLoc> typeLoc; /// \c b. /// /// Usable as: Any Matcher -template <typename M1, typename M2> -internal::PolymorphicMatcherWithParam2<internal::EachOfMatcher, M1, M2> -eachOf(const M1 &P1, const M2 &P2) { - return internal::PolymorphicMatcherWithParam2<internal::EachOfMatcher, M1, - M2>(P1, P2); -} - -/// \brief Various overloads for the anyOf matcher. -/// @{ +const internal::VariadicOperatorMatcherFunc eachOf = { + internal::EachOfVariadicOperator +}; /// \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, - M1, M2 >(P1, P2); -} -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 M1, typename M2, typename M3, typename M4> -internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1, - internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2, - internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, - 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 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, - 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. -/// @{ +const internal::VariadicOperatorMatcherFunc anyOf = { + internal::AnyOfVariadicOperator +}; /// \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, M1, M2>( - P1, P2); -} -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)); -} -template <typename M1, typename M2, typename M3, typename M4> -internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M1, - internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M2, internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M3, M4> > > -allOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) { - return allOf(P1, allOf(P2, P3, P4)); -} -template <typename M1, typename M2, typename M3, typename M4, typename M5> -internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M1, - internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M2, - internal::PolymorphicMatcherWithParam2< - internal::AllOfMatcher, M3, - internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M4, - M5> > > > -allOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) { - return allOf(P1, allOf(P2, P3, P4, P5)); -} - -/// @} +const internal::VariadicOperatorMatcherFunc allOf = { + internal::AllOfVariadicOperator +}; /// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) /// @@ -1412,10 +1460,13 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { /// /// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<CXXMethodDecl> inline internal::PolymorphicMatcherWithParam1< - internal::HasOverloadedOperatorNameMatcher, StringRef> + internal::HasOverloadedOperatorNameMatcher, StringRef, + AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)> hasOverloadedOperatorName(const StringRef Name) { return internal::PolymorphicMatcherWithParam1< - internal::HasOverloadedOperatorNameMatcher, StringRef>(Name); + internal::HasOverloadedOperatorNameMatcher, StringRef, + AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)>( + Name); } /// \brief Matches C++ classes that are directly or indirectly derived from @@ -1445,24 +1496,25 @@ AST_MATCHER_P(CXXRecordDecl, isDerivedFrom, } /// \brief Overloaded method as shortcut for \c isDerivedFrom(hasName(...)). -inline internal::Matcher<CXXRecordDecl> isDerivedFrom(StringRef BaseName) { +AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isDerivedFrom, StringRef, BaseName, 1) { assert(!BaseName.empty()); - return isDerivedFrom(hasName(BaseName)); + return isDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder); } /// \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)); +AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, + internal::Matcher<NamedDecl>, Base, 0) { + return Matcher<CXXRecordDecl>(anyOf(Base, isDerivedFrom(Base))) + .matches(Node, Finder, Builder); } /// \brief Overloaded method as shortcut for /// \c isSameOrDerivedFrom(hasName(...)). -inline internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom( - StringRef BaseName) { +AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, StringRef, BaseName, + 1) { assert(!BaseName.empty()); - return isSameOrDerivedFrom(hasName(BaseName)); + return isSameOrDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder); } /// \brief Matches the first method of a class or struct that satisfies \c @@ -1478,12 +1530,8 @@ inline internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom( /// but not \c B. AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>, InnerMatcher) { - for (CXXRecordDecl::method_iterator I = Node.method_begin(), - E = Node.method_end(); - I != E; ++I) - if (InnerMatcher.matches(**I, Finder, Builder)) - return true; - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.method_begin(), + Node.method_end(), Finder, Builder); } /// \brief Matches AST nodes that have child AST nodes that match the @@ -1499,12 +1547,8 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>, /// 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) { - return internal::ArgumentAdaptingMatcher<internal::HasMatcher, - ChildT>(ChildMatcher); -} +const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> +LLVM_ATTRIBUTE_UNUSED has = {}; /// \brief Matches AST nodes that have descendant AST nodes that match the /// provided matcher. @@ -1520,13 +1564,8 @@ internal::ArgumentAdaptingMatcher<internal::HasMatcher, ChildT> has( /// 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) { - return internal::ArgumentAdaptingMatcher< - internal::HasDescendantMatcher, - DescendantT>(DescendantMatcher); -} +const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher> +LLVM_ATTRIBUTE_UNUSED hasDescendant = {}; /// \brief Matches AST nodes that have child AST nodes that match the /// provided matcher. @@ -1544,13 +1583,8 @@ hasDescendant(const internal::Matcher<DescendantT> &DescendantMatcher) { /// 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) { - return internal::ArgumentAdaptingMatcher< - internal::ForEachMatcher, - ChildT>(ChildMatcher); -} +const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher> +LLVM_ATTRIBUTE_UNUSED forEach = {}; /// \brief Matches AST nodes that have descendant AST nodes that match the /// provided matcher. @@ -1576,15 +1610,8 @@ internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach( /// \endcode /// /// Usable as: Any Matcher -template <typename DescendantT> -internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher, - DescendantT> -forEachDescendant( - const internal::Matcher<DescendantT> &DescendantMatcher) { - return internal::ArgumentAdaptingMatcher< - internal::ForEachDescendantMatcher, - DescendantT>(DescendantMatcher); -} +const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher> +LLVM_ATTRIBUTE_UNUSED forEachDescendant = {}; /// \brief Matches if the node or any descendant matches. /// @@ -1602,10 +1629,7 @@ forEachDescendant( /// /// Usable as: Any Matcher template <typename T> -internal::PolymorphicMatcherWithParam2< - internal::EachOfMatcher, internal::Matcher<T>, - internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher, T> > -findAll(const internal::Matcher<T> &Matcher) { +internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) { return eachOf(Matcher, forEachDescendant(Matcher)); } @@ -1619,13 +1643,9 @@ findAll(const internal::Matcher<T> &Matcher) { /// \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); -} +const internal::ArgumentAdaptingMatcherFunc< + internal::HasParentMatcher, internal::TypeList<Decl, Stmt>, + internal::TypeList<Decl, Stmt> > LLVM_ATTRIBUTE_UNUSED hasParent = {}; /// \brief Matches AST nodes that have an ancestor that matches the provided /// matcher. @@ -1638,13 +1658,9 @@ hasParent(const internal::Matcher<ParentT> &ParentMatcher) { /// \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); -} +const internal::ArgumentAdaptingMatcherFunc< + internal::HasAncestorMatcher, internal::TypeList<Decl, Stmt>, + internal::TypeList<Decl, Stmt> > LLVM_ATTRIBUTE_UNUSED hasAncestor = {}; /// \brief Matches if the provided matcher does not match. /// @@ -1662,22 +1678,31 @@ unless(const M &InnerMatcher) { internal::NotMatcher, M>(InnerMatcher); } -/// \brief Matches a type if the declaration of the type matches the given -/// matcher. +/// \brief Matches a node if the declaration associated with that node +/// matches the given matcher. +/// +/// The associated declaration is: +/// - for type nodes, the declaration of the underlying type +/// - for CallExpr, the declaration of the callee +/// - for MemberExpr, the declaration of the referenced member +/// - for CXXConstructExpr, the declaration of the constructor /// -/// In addition to being usable as Matcher<TypedefType>, also usable as -/// Matcher<T> for any T supporting the getDecl() member function. e.g. various -/// subtypes of clang::Type. +/// Also usable as Matcher<T> for any T supporting the getDecl() member +/// function. e.g. various subtypes of clang::Type and various expressions. /// -/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, -/// Matcher<MemberExpr>, Matcher<TypedefType>, -/// Matcher<TemplateSpecializationType> -inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher, - internal::Matcher<Decl> > - hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) { +/// Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, +/// Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, +/// Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, +/// Matcher<RecordType>, Matcher<TagType>, +/// Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, +/// Matcher<TypedefType>, Matcher<UnresolvedUsingType> +inline internal::PolymorphicMatcherWithParam1< + internal::HasDeclarationMatcher, internal::Matcher<Decl>, + void(internal::HasDeclarationSupportedTypes)> +hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) { return internal::PolymorphicMatcherWithParam1< - internal::HasDeclarationMatcher, - internal::Matcher<Decl> >(InnerMatcher); + internal::HasDeclarationMatcher, internal::Matcher<Decl>, + void(internal::HasDeclarationSupportedTypes)>(InnerMatcher); } /// \brief Matches on the implicit object argument of a member call expression. @@ -1728,9 +1753,9 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>, /// class Y { public: void x(); }; /// void z() { Y y; y.x(); /// \endcode -inline internal::Matcher<CallExpr> callee( - const internal::Matcher<Decl> &InnerMatcher) { - return callExpr(hasDeclaration(InnerMatcher)); +AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher, + 1) { + return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder); } /// \brief Matches if the expression's or declaration's type matches a type @@ -1742,11 +1767,9 @@ inline internal::Matcher<CallExpr> callee( /// 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 || - llvm::is_base_of<ValueDecl, NodeType>::value), - instantiated_with_wrong_types); +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl), + internal::Matcher<QualType>, InnerMatcher, 0) { return InnerMatcher.matches(Node.getType(), Finder, Builder); } @@ -1767,11 +1790,27 @@ AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<QualType>, /// \endcode /// /// Usable as: Matcher<Expr>, Matcher<ValueDecl> -inline internal::PolymorphicMatcherWithParam1< - internal::matcher_hasType0Matcher, - internal::Matcher<QualType> > -hasType(const internal::Matcher<Decl> &InnerMatcher) { - return hasType(qualType(hasDeclaration(InnerMatcher))); +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl), + internal::Matcher<Decl>, InnerMatcher, 1) { + return qualType(hasDeclaration(InnerMatcher)) + .matches(Node.getType(), Finder, Builder); +} + +/// \brief Matches if the type location of the declarator decl's type matches +/// the inner matcher. +/// +/// Given +/// \code +/// int x; +/// \endcode +/// declaratorDecl(hasTypeLoc(loc(asString("int")))) +/// matches int x +AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher<TypeLoc>, Inner) { + if (!Node.getTypeSourceInfo()) + // This happens for example for implicit destructors. + return false; + return Inner.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder, Builder); } /// \brief Matches if the matched type is represented by the given string. @@ -1804,9 +1843,10 @@ AST_MATCHER_P( } /// \brief Overloaded to match the pointee type's declaration. -inline internal::Matcher<QualType> pointsTo( - const internal::Matcher<Decl> &InnerMatcher) { - return pointsTo(qualType(hasDeclaration(InnerMatcher))); +AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>, + InnerMatcher, 1) { + return pointsTo(qualType(hasDeclaration(InnerMatcher))) + .matches(Node, Finder, Builder); } /// \brief Matches if the matched type is a reference type and the referenced @@ -1841,13 +1881,16 @@ AST_MATCHER_P(QualType, references, internal::Matcher<QualType>, /// varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does. AST_MATCHER_P(QualType, hasCanonicalType, internal::Matcher<QualType>, InnerMatcher) { + if (Node.isNull()) + return false; return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder); } /// \brief Overloaded to match the referenced type's declaration. -inline internal::Matcher<QualType> references( - const internal::Matcher<Decl> &InnerMatcher) { - return references(qualType(hasDeclaration(InnerMatcher))); +AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>, + InnerMatcher, 1) { + return references(qualType(hasDeclaration(InnerMatcher))) + .matches(Node, Finder, Builder); } AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, @@ -1859,17 +1902,19 @@ AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, /// \brief Matches if the expression's type either matches the specified /// matcher, or is a pointer to a type that matches the InnerMatcher. -inline internal::Matcher<CXXMemberCallExpr> thisPointerType( - const internal::Matcher<QualType> &InnerMatcher) { +AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, + internal::Matcher<QualType>, InnerMatcher, 0) { return onImplicitObjectArgument( - anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))); + anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))) + .matches(Node, Finder, Builder); } /// \brief Overloaded to match the type's declaration. -inline internal::Matcher<CXXMemberCallExpr> thisPointerType( - const internal::Matcher<Decl> &InnerMatcher) { +AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, + internal::Matcher<Decl>, InnerMatcher, 1) { return onImplicitObjectArgument( - anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))); + anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))) + .matches(Node, Finder, Builder); } /// \brief Matches a DeclRefExpr that refers to a declaration that matches the @@ -1953,11 +1998,9 @@ AST_MATCHER_P( /// 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, - NodeType>::value), - instantiated_with_wrong_types); +AST_POLYMORPHIC_MATCHER_P(argumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES_2( + CallExpr, CXXConstructExpr), + unsigned, N) { return Node.getNumArgs() == N; } @@ -1970,11 +2013,9 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) { /// 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 || - llvm::is_base_of<CXXConstructExpr, - NodeType>::value), - instantiated_with_wrong_types); + hasArgument, + AST_POLYMORPHIC_SUPPORTED_TYPES_2(CallExpr, CXXConstructExpr), + unsigned, N, internal::Matcher<Expr>, InnerMatcher) { return (N < Node.getNumArgs() && InnerMatcher.matches( *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder)); @@ -2037,13 +2078,8 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N, /// record matches Foo, hasAnyConstructorInitializer matches foo_(1) AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, internal::Matcher<CXXCtorInitializer>, InnerMatcher) { - for (CXXConstructorDecl::init_const_iterator I = Node.init_begin(); - I != Node.init_end(); ++I) { - if (InnerMatcher.matches(**I, Finder, Builder)) { - return true; - } - } - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.init_begin(), + Node.init_end(), Finder, Builder); } /// \brief Matches the field declaration of a constructor initializer. @@ -2086,7 +2122,7 @@ AST_MATCHER_P(CXXCtorInitializer, withInitializer, InnerMatcher.matches(*NodeAsExpr, Finder, Builder)); } -/// \brief Matches a contructor initializer if it is explicitly written in +/// \brief Matches a constructor initializer if it is explicitly written in /// code (as opposed to implicitly added by the compiler). /// /// Given @@ -2120,15 +2156,19 @@ AST_MATCHER(CXXConstructorDecl, isImplicit) { /// matches x(1, y, 42) /// with hasAnyArgument(...) /// matching y -AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, internal::Matcher<Expr>, - InnerMatcher) { - TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value || - llvm::is_base_of<CXXConstructExpr, - NodeType>::value), - instantiated_with_wrong_types); +/// +/// FIXME: Currently this will ignore parentheses and implicit casts on +/// the argument before applying the inner matcher. We'll want to remove +/// this to allow for greater control by the user once \c ignoreImplicit() +/// has been implemented. +AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES_2( + CallExpr, CXXConstructExpr), + internal::Matcher<Expr>, InnerMatcher) { for (unsigned I = 0; I < Node.getNumArgs(); ++I) { - if (InnerMatcher.matches(*Node.getArg(I)->IgnoreParenImpCasts(), - Finder, Builder)) { + BoundNodesTreeBuilder Result(*Builder); + if (InnerMatcher.matches(*Node.getArg(I)->IgnoreParenImpCasts(), Finder, + &Result)) { + *Builder = Result; return true; } } @@ -2167,12 +2207,8 @@ AST_MATCHER_P2(FunctionDecl, hasParameter, /// matching int y AST_MATCHER_P(FunctionDecl, hasAnyParameter, internal::Matcher<ParmVarDecl>, InnerMatcher) { - for (unsigned I = 0; I < Node.getNumParams(); ++I) { - if (InnerMatcher.matches(*Node.getParamDecl(I), Finder, Builder)) { - return true; - } - } - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(), + Node.param_end(), Finder, Builder); } /// \brief Matches \c FunctionDecls that have a specific parameter count. @@ -2222,27 +2258,68 @@ AST_MATCHER(FunctionDecl, isExternC) { /// \code /// if (true) {} /// \endcode -AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher<Expr>, - InnerMatcher) { - TOOLING_COMPILE_ASSERT( - (llvm::is_base_of<IfStmt, NodeType>::value) || - (llvm::is_base_of<ForStmt, NodeType>::value) || - (llvm::is_base_of<WhileStmt, NodeType>::value) || - (llvm::is_base_of<DoStmt, NodeType>::value) || - (llvm::is_base_of<ConditionalOperator, NodeType>::value), - has_condition_requires_if_statement_conditional_operator_or_loop); +AST_POLYMORPHIC_MATCHER_P( + hasCondition, AST_POLYMORPHIC_SUPPORTED_TYPES_5( + IfStmt, ForStmt, WhileStmt, DoStmt, ConditionalOperator), + internal::Matcher<Expr>, InnerMatcher) { const Expr *const Condition = Node.getCond(); return (Condition != NULL && InnerMatcher.matches(*Condition, Finder, Builder)); } +namespace internal { +struct NotEqualsBoundNodePredicate { + bool operator()(const internal::BoundNodesMap &Nodes) const { + return Nodes.getNode(ID) != Node; + } + std::string ID; + ast_type_traits::DynTypedNode Node; +}; +} // namespace internal + +/// \brief Matches if a node equals a previously bound node. +/// +/// Matches a node if it equals the node previously bound to \p ID. +/// +/// Given +/// \code +/// class X { int a; int b; }; +/// \endcode +/// recordDecl( +/// has(fieldDecl(hasName("a"), hasType(type().bind("t")))), +/// has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))) +/// matches the class \c X, as \c a and \c b have the same type. +/// +/// Note that when multiple matches are involved via \c forEach* matchers, +/// \c equalsBoundNodes acts as a filter. +/// For example: +/// compoundStmt( +/// forEachDescendant(varDecl().bind("d")), +/// forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))) +/// will trigger a match for each combination of variable declaration +/// and reference to that variable declaration within a compound statement. +AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, AST_POLYMORPHIC_SUPPORTED_TYPES_4( + Stmt, Decl, Type, QualType), + std::string, ID) { + // FIXME: Figure out whether it makes sense to allow this + // on any other node types. + // For *Loc it probably does not make sense, as those seem + // unique. For NestedNameSepcifier it might make sense, as + // those also have pointer identity, but I'm not sure whether + // they're ever reused. + internal::NotEqualsBoundNodePredicate Predicate; + Predicate.ID = ID; + Predicate.Node = ast_type_traits::DynTypedNode::create(Node); + return Builder->removeBindings(Predicate); +} + /// \brief Matches the condition variable statement in an if statement. /// /// Given /// \code /// if (A* a = GetAPointer()) {} /// \endcode -/// hasConditionVariableStatment(...) +/// hasConditionVariableStatement(...) /// matches 'A* a = GetAPointer()'. AST_MATCHER_P(IfStmt, hasConditionVariableStatement, internal::Matcher<DeclStmt>, InnerMatcher) { @@ -2296,13 +2373,9 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, /// matches 'for (;;) {}' /// with compoundStmt() /// matching '{}' -AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher<Stmt>, - InnerMatcher) { - TOOLING_COMPILE_ASSERT( - (llvm::is_base_of<DoStmt, NodeType>::value) || - (llvm::is_base_of<ForStmt, NodeType>::value) || - (llvm::is_base_of<WhileStmt, NodeType>::value), - has_body_requires_for_while_or_do_statement); +AST_POLYMORPHIC_MATCHER_P( + hasBody, AST_POLYMORPHIC_SUPPORTED_TYPES_3(DoStmt, ForStmt, WhileStmt), + internal::Matcher<Stmt>, InnerMatcher) { const Stmt *const Statement = Node.getBody(); return (Statement != NULL && InnerMatcher.matches(*Statement, Finder, Builder)); @@ -2321,12 +2394,8 @@ AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher<Stmt>, /// matching '{}' AST_MATCHER_P(CompoundStmt, hasAnySubstatement, internal::Matcher<Stmt>, InnerMatcher) { - for (CompoundStmt::const_body_iterator It = Node.body_begin(); - It != Node.body_end(); - ++It) { - if (InnerMatcher.matches(**It, Finder, Builder)) return true; - } - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.body_begin(), + Node.body_end(), Finder, Builder); } /// \brief Checks that a compound statement contains a specific number of @@ -2367,11 +2436,9 @@ equals(const ValueT &Value) { /// \code /// !(a || b) /// \endcode -AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) { - TOOLING_COMPILE_ASSERT( - (llvm::is_base_of<BinaryOperator, NodeType>::value) || - (llvm::is_base_of<UnaryOperator, NodeType>::value), - has_condition_requires_if_statement_or_conditional_operator); +AST_POLYMORPHIC_MATCHER_P(hasOperatorName, AST_POLYMORPHIC_SUPPORTED_TYPES_2( + BinaryOperator, UnaryOperator), + std::string, Name) { return Name == Node.getOpcodeStr(Node.getOpcode()); } @@ -2493,12 +2560,8 @@ AST_MATCHER_P(ConditionalOperator, hasFalseExpression, /// \endcode /// /// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl> -AST_POLYMORPHIC_MATCHER(isDefinition) { - TOOLING_COMPILE_ASSERT( - (llvm::is_base_of<TagDecl, NodeType>::value) || - (llvm::is_base_of<VarDecl, NodeType>::value) || - (llvm::is_base_of<FunctionDecl, NodeType>::value), - is_definition_requires_isThisDeclarationADefinition_method); +AST_POLYMORPHIC_MATCHER(isDefinition, AST_POLYMORPHIC_SUPPORTED_TYPES_3( + TagDecl, VarDecl, FunctionDecl)) { return Node.isThisDeclarationADefinition(); } @@ -2540,6 +2603,21 @@ AST_MATCHER(CXXMethodDecl, isVirtual) { return Node.isVirtual(); } +/// \brief Matches if the given method declaration is const. +/// +/// Given +/// \code +/// struct A { +/// void foo() const; +/// void bar(); +/// }; +/// \endcode +/// +/// methodDecl(isConst()) matches A::foo() but not A::bar() +AST_MATCHER(CXXMethodDecl, isConst) { + return Node.isConst(); +} + /// \brief Matches if the given method declaration overrides another method. /// /// Given @@ -2672,12 +2750,8 @@ AST_MATCHER_P(MemberExpr, hasObjectExpression, /// matches \code using X::b \endcode AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl, internal::Matcher<UsingShadowDecl>, InnerMatcher) { - for (UsingDecl::shadow_iterator II = Node.shadow_begin(); - II != Node.shadow_end(); ++II) { - if (InnerMatcher.matches(**II, Finder, Builder)) - return true; - } - return false; + return matchesFirstInPointerRange(InnerMatcher, Node.shadow_begin(), + Node.shadow_end(), Finder, Builder); } /// \brief Matches a using shadow declaration where the target declaration is @@ -2720,11 +2794,9 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, /// does not match, as X<A> is an explicit template specialization. /// /// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> -AST_POLYMORPHIC_MATCHER(isTemplateInstantiation) { - TOOLING_COMPILE_ASSERT((llvm::is_base_of<FunctionDecl, NodeType>::value) || - (llvm::is_base_of<VarDecl, NodeType>::value) || - (llvm::is_base_of<CXXRecordDecl, NodeType>::value), - requires_getTemplateSpecializationKind_method); +AST_POLYMORPHIC_MATCHER( + isTemplateInstantiation, + AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) { return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation || Node.getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition); @@ -2742,11 +2814,9 @@ AST_POLYMORPHIC_MATCHER(isTemplateInstantiation) { /// matches the specialization A<int>(). /// /// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> -AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization) { - TOOLING_COMPILE_ASSERT((llvm::is_base_of<FunctionDecl, NodeType>::value) || - (llvm::is_base_of<VarDecl, NodeType>::value) || - (llvm::is_base_of<CXXRecordDecl, NodeType>::value), - requires_getTemplateSpecializationKind_method); +AST_POLYMORPHIC_MATCHER( + isExplicitTemplateSpecialization, + AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) { return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization); } @@ -2807,7 +2877,9 @@ AST_TYPE_MATCHER(ComplexType, complexType); /// matches "int b[7]" /// /// Usable as: Matcher<ArrayType>, Matcher<ComplexType> -AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement); +AST_TYPELOC_TRAVERSE_MATCHER( + hasElementType, getElement, + AST_POLYMORPHIC_SUPPORTED_TYPES_2(ArrayType, ComplexType)); /// \brief Matches C arrays with a specified constant size. /// @@ -2914,7 +2986,8 @@ AST_TYPE_MATCHER(AtomicType, atomicType); /// matches "_Atomic(int) i" /// /// Usable as: Matcher<AtomicType> -AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue); +AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue, + AST_POLYMORPHIC_SUPPORTED_TYPES_1(AtomicType)); /// \brief Matches types nodes representing C++11 auto types. /// @@ -2942,7 +3015,8 @@ AST_TYPE_MATCHER(AutoType, autoType); /// matches "auto a" /// /// Usable as: Matcher<AutoType> -AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType); +AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, + AST_POLYMORPHIC_SUPPORTED_TYPES_1(AutoType)); /// \brief Matches \c FunctionType nodes. /// @@ -2979,7 +3053,8 @@ AST_TYPE_MATCHER(ParenType, parenType); /// \c ptr_to_func but not \c ptr_to_array. /// /// Usable as: Matcher<ParenType> -AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType); +AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType, + AST_POLYMORPHIC_SUPPORTED_TYPES_1(ParenType)); /// \brief Matches block pointer types, i.e. types syntactically represented as /// "void (^)(int)". @@ -3073,7 +3148,10 @@ AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType); /// /// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, /// Matcher<PointerType>, Matcher<ReferenceType> -AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee); +AST_TYPELOC_TRAVERSE_MATCHER( + pointee, getPointee, + AST_POLYMORPHIC_SUPPORTED_TYPES_4(BlockPointerType, MemberPointerType, + PointerType, ReferenceType)); /// \brief Matches typedef types. /// @@ -3100,6 +3178,16 @@ AST_TYPE_MATCHER(TypedefType, typedefType); /// instantiation in \c A and the type of the variable declaration in \c B. AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType); +/// \brief Matches types nodes representing unary type transformations. +/// +/// Given: +/// \code +/// typedef __underlying_type(T) type; +/// \endcode +/// unaryTransformType() +/// matches "__underlying_type(T)" +AST_TYPE_MATCHER(UnaryTransformType, unaryTransformType); + /// \brief Matches record types (e.g. structs, classes). /// /// Given @@ -3331,6 +3419,80 @@ AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, Stmt*, Other, 1) { /// @} +/// \brief Matches each case or default statement belonging to the given switch +/// statement. This matcher may produce multiple matches. +/// +/// Given +/// \code +/// switch (1) { case 1: case 2: default: switch (2) { case 3: case 4: ; } } +/// \endcode +/// switchStmt(forEachSwitchCase(caseStmt().bind("c"))).bind("s") +/// matches four times, with "c" binding each of "case 1:", "case 2:", +/// "case 3:" and "case 4:", and "s" respectively binding "switch (1)", +/// "switch (1)", "switch (2)" and "switch (2)". +AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>, + InnerMatcher) { + BoundNodesTreeBuilder Result; + // FIXME: getSwitchCaseList() does not necessarily guarantee a stable + // iteration order. We should use the more general iterating matchers once + // they are capable of expressing this matcher (for example, it should ignore + // case statements belonging to nested switch statements). + bool Matched = false; + for (const SwitchCase *SC = Node.getSwitchCaseList(); SC; + SC = SC->getNextSwitchCase()) { + BoundNodesTreeBuilder CaseBuilder(*Builder); + bool CaseMatched = InnerMatcher.matches(*SC, Finder, &CaseBuilder); + if (CaseMatched) { + Matched = true; + Result.addMatch(CaseBuilder); + } + } + *Builder = Result; + return Matched; +} + +/// \brief Matches each constructor initializer in a constructor definition. +/// +/// Given +/// \code +/// class A { A() : i(42), j(42) {} int i; int j; }; +/// \endcode +/// constructorDecl(forEachConstructorInitializer(forField(decl().bind("x")))) +/// will trigger two matches, binding for 'i' and 'j' respectively. +AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer, + internal::Matcher<CXXCtorInitializer>, InnerMatcher) { + BoundNodesTreeBuilder Result; + bool Matched = false; + for (CXXConstructorDecl::init_const_iterator I = Node.init_begin(), + E = Node.init_end(); + I != E; ++I) { + BoundNodesTreeBuilder InitBuilder(*Builder); + if (InnerMatcher.matches(**I, Finder, &InitBuilder)) { + Matched = true; + Result.addMatch(InitBuilder); + } + } + *Builder = Result; + return Matched; +} + +/// \brief If the given case statement does not use the GNU case range +/// extension, matches the constant given in the statement. +/// +/// Given +/// \code +/// switch (1) { case 1: case 1+1: case 3 ... 4: ; } +/// \endcode +/// caseStmt(hasCaseConstant(integerLiteral())) +/// matches "case 1:" +AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>, + InnerMatcher) { + if (Node.getRHS()) + return false; + + return InnerMatcher.matches(*Node.getLHS(), 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 30691ad..69cee2e 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -36,12 +36,13 @@ #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H #include "clang/AST/ASTTypeTraits.h" -#include "clang/AST/DeclCXX.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/ExprCXX.h" -#include "clang/AST/StmtCXX.h" #include "clang/AST/Stmt.h" +#include "clang/AST/StmtCXX.h" #include "clang/AST/Type.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/VariadicFunction.h" #include "llvm/Support/type_traits.h" #include <map> @@ -60,7 +61,6 @@ class BoundNodes; namespace internal { -class BoundNodesTreeBuilder; /// \brief Internal version of BoundNodes. Holds all the bound nodes. class BoundNodesMap { public: @@ -71,9 +71,6 @@ public: 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. /// @@ -88,29 +85,39 @@ public: return It->second.get<T>(); } - /// \brief Copies all ID/Node pairs to BoundNodesTreeBuilder \c Builder. - void copyTo(BoundNodesTreeBuilder *Builder) const; + ast_type_traits::DynTypedNode getNode(StringRef ID) const { + IDToNodeMap::const_iterator It = NodeMap.find(ID); + if (It == NodeMap.end()) { + return ast_type_traits::DynTypedNode(); + } + return It->second; + } - /// \brief Copies all ID/Node pairs to BoundNodesMap \c Other. - void copyTo(BoundNodesMap *Other) const; + /// \brief Imposes an order on BoundNodesMaps. + bool operator<(const BoundNodesMap &Other) const { + return NodeMap < Other.NodeMap; + } -private: /// \brief A map from IDs to the bound nodes. + /// + /// Note that we're using std::map here, as for memoization: + /// - we need a comparison operator + /// - we need an assignment operator typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap; + const IDToNodeMap &getMap() const { + return NodeMap; + } + +private: IDToNodeMap NodeMap; }; -/// \brief A tree of bound nodes in match results. -/// -/// If a match can contain multiple matches on the same node with different -/// matching subexpressions, BoundNodesTree contains a branch for each of -/// those matching subexpressions. +/// \brief Creates BoundNodesTree objects. /// -/// BoundNodesTree's are created during the matching process; when a match -/// is found, we iterate over the tree and create a BoundNodes object containing -/// the union of all bound nodes on the path from the root to a each leaf. -class BoundNodesTree { +/// The tree builder is used during the matching process to insert the bound +/// nodes from the Id matcher. +class BoundNodesTreeBuilder { public: /// \brief A visitor interface to visit all BoundNodes results for a /// BoundNodesTree. @@ -124,63 +131,36 @@ public: virtual void visitMatch(const BoundNodes& BoundNodesView) = 0; }; - BoundNodesTree(); - - /// \brief Create a BoundNodesTree from pre-filled maps of bindings. - BoundNodesTree(const BoundNodesMap& Bindings, - const std::vector<BoundNodesTree> RecursiveBindings); + /// \brief Add a binding from an id to a node. + template <typename T> void setBinding(const std::string &Id, const T *Node) { + if (Bindings.empty()) + Bindings.push_back(BoundNodesMap()); + for (unsigned i = 0, e = Bindings.size(); i != e; ++i) + Bindings[i].addNode(Id, Node); + } - /// \brief Adds all bound nodes to \c Builder. - void copyTo(BoundNodesTreeBuilder* Builder) const; + /// \brief Adds a branch in the tree. + void addMatch(const BoundNodesTreeBuilder &Bindings); /// \brief Visits all matches that this BoundNodesTree represents. /// /// The ownership of 'ResultVisitor' remains at the caller. void visitMatches(Visitor* ResultVisitor); -private: - void visitMatchesRecursively( - Visitor* ResultVistior, - const BoundNodesMap& AggregatedBindings); - - // FIXME: Find out whether we want to use different data structures here - - // first benchmarks indicate that it doesn't matter though. - - BoundNodesMap Bindings; - - std::vector<BoundNodesTree> RecursiveBindings; -}; - -/// \brief Creates BoundNodesTree objects. -/// -/// The tree builder is used during the matching process to insert the bound -/// nodes from the Id matcher. -class BoundNodesTreeBuilder { -public: - BoundNodesTreeBuilder(); - - /// \brief Add a binding from an id to a 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); + template <typename ExcludePredicate> + bool removeBindings(const ExcludePredicate &Predicate) { + Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate), + Bindings.end()); + return !Bindings.empty(); } - /// \brief Adds a branch in the tree. - void addMatch(const BoundNodesTree& Bindings); - - /// \brief Returns a BoundNodes object containing all current bindings. - BoundNodesTree build() const; + /// \brief Imposes an order on BoundNodesTreeBuilders. + bool operator<(const BoundNodesTreeBuilder &Other) const { + return Bindings < Other.Bindings; + } private: - BoundNodesTreeBuilder(const BoundNodesTreeBuilder &) LLVM_DELETED_FUNCTION; - void operator=(const BoundNodesTreeBuilder &) LLVM_DELETED_FUNCTION; - - BoundNodesMap Bindings; - - std::vector<BoundNodesTree> RecursiveBindings; + SmallVector<BoundNodesMap, 16> Bindings; }; class ASTMatchFinder; @@ -225,24 +205,6 @@ 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 @@ -252,7 +214,7 @@ public: /// operator rather than a type hierarchy to be able to templatize the /// type hierarchy instead of spelling it out. template <typename T> -class Matcher : public DynTypedMatcher { +class Matcher { public: /// \brief Takes ownership of the provided implementation pointer. explicit Matcher(MatcherInterface<T> *Implementation) @@ -282,7 +244,13 @@ public: bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - return Implementation->matches(Node, Finder, Builder); + if (Implementation->matches(Node, Finder, Builder)) + return true; + // Delete all bindings when a matcher does not match. + // This prevents unexpected exposure of bound nodes in unmatches + // branches of the match tree. + *Builder = BoundNodesTreeBuilder(); + return false; } /// \brief Returns an ID that uniquely identifies the matcher. @@ -292,15 +260,6 @@ 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>. /// @@ -353,6 +312,217 @@ inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) { return Matcher<T>(Implementation); } +template <typename T> class BindableMatcher; + +/// \brief Matcher that works on a \c DynTypedNode. +/// +/// It is constructed from a \c Matcher<T> object and redirects most calls to +/// underlying matcher. +/// It checks whether the \c DynTypedNode is convertible into the type of the +/// underlying matcher and then do the actual match on the actual node, or +/// return false if it is not convertible. +class DynTypedMatcher { +public: + /// \brief Construct from a \c Matcher<T>. Copies the matcher. + template <typename T> inline DynTypedMatcher(const Matcher<T> &M); + + /// \brief Construct from a bindable \c Matcher<T>. Copies the matcher. + /// + /// This version enables \c tryBind() on the \c DynTypedMatcher. + template <typename T> inline DynTypedMatcher(const BindableMatcher<T> &M); + + /// \brief Returns true if the matcher matches the given \c DynNode. + bool matches(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { + return Storage->matches(DynNode, Finder, Builder); + } + + /// \brief Bind the specified \p ID to the matcher. + /// \return A new matcher with the \p ID bound to it if this matcher supports + /// binding. Otherwise, returns an empty \c Optional<>. + llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const { + return Storage->tryBind(ID); + } + + /// \brief Returns a unique \p ID for the matcher. + uint64_t getID() const { return Storage->getID(); } + + /// \brief Returns the type this matcher works on. + /// + /// \c matches() will always return false unless the node passed is of this + /// or a derived type. + ast_type_traits::ASTNodeKind getSupportedKind() const { + return Storage->getSupportedKind(); + } + + /// \brief Returns \c true if the passed \c DynTypedMatcher can be converted + /// to a \c Matcher<T>. + /// + /// This method verifies that the underlying matcher in \c Other can process + /// nodes of types T. + template <typename T> bool canConvertTo() const { + return getSupportedKind().isBaseOf( + ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); + } + + /// \brief Construct a \c Matcher<T> interface around the dynamic matcher. + /// + /// This method asserts that \c canConvertTo() is \c true. Callers + /// should call \c canConvertTo() first to make sure that \c this is + /// compatible with T. + template <typename T> Matcher<T> convertTo() const { + assert(canConvertTo<T>()); + return unconditionalConvertTo<T>(); + } + + /// \brief Same as \c convertTo(), but does not check that the underlying + /// matcher can handle a value of T. + /// + /// If it is not compatible, then this matcher will never match anything. + template <typename T> Matcher<T> unconditionalConvertTo() const { + return Matcher<T>(new WrappedMatcher<T>(*this)); + } + +private: + class MatcherStorage : public RefCountedBaseVPTR { + public: + MatcherStorage(ast_type_traits::ASTNodeKind SupportedKind, uint64_t ID) + : SupportedKind(SupportedKind), ID(ID) {} + virtual ~MatcherStorage(); + + virtual bool matches(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const = 0; + + virtual llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const = 0; + + ast_type_traits::ASTNodeKind getSupportedKind() const { + return SupportedKind; + } + + uint64_t getID() const { return ID; } + + private: + const ast_type_traits::ASTNodeKind SupportedKind; + const uint64_t ID; + }; + + /// \brief Typed implementation of \c MatcherStorage. + template <typename T> class TypedMatcherStorage; + + /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher. + template <typename T> class WrappedMatcher; + + IntrusiveRefCntPtr<const MatcherStorage> Storage; +}; + +template <typename T> +class DynTypedMatcher::TypedMatcherStorage : public MatcherStorage { +public: + TypedMatcherStorage(const Matcher<T> &Other, bool AllowBind) + : MatcherStorage(ast_type_traits::ASTNodeKind::getFromNodeKind<T>(), + Other.getID()), + InnerMatcher(Other), AllowBind(AllowBind) {} + + bool matches(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const + LLVM_OVERRIDE { + if (const T *Node = DynNode.get<T>()) { + return InnerMatcher.matches(*Node, Finder, Builder); + } + return false; + } + + llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const LLVM_OVERRIDE { + if (!AllowBind) + return llvm::Optional<DynTypedMatcher>(); + return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID)); + } + +private: + const Matcher<T> InnerMatcher; + const bool AllowBind; +}; + +template <typename T> +inline DynTypedMatcher::DynTypedMatcher(const Matcher<T> &M) + : Storage(new TypedMatcherStorage<T>(M, false)) {} + +template <typename T> +inline DynTypedMatcher::DynTypedMatcher(const BindableMatcher<T> &M) + : Storage(new TypedMatcherStorage<T>(M, true)) {} + +template <typename T> +class DynTypedMatcher::WrappedMatcher : public MatcherInterface<T> { +public: + explicit WrappedMatcher(const DynTypedMatcher &Matcher) : Inner(Matcher) {} + virtual ~WrappedMatcher() {} + + bool matches(const T &Node, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return Inner.matches(ast_type_traits::DynTypedNode::create(Node), Finder, + Builder); + } + +private: + const DynTypedMatcher Inner; +}; + +/// \brief Specialization of the conversion functions for QualType. +/// +/// These specializations provide the Matcher<Type>->Matcher<QualType> +/// conversion that the static API does. +template <> inline bool DynTypedMatcher::canConvertTo<QualType>() const { + const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind(); + return SourceKind.isSame( + ast_type_traits::ASTNodeKind::getFromNodeKind<Type>()) || + SourceKind.isSame( + ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>()); +} + +template <> +inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const { + assert(canConvertTo<QualType>()); + const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind(); + if (SourceKind.isSame( + ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) { + // We support implicit conversion from Matcher<Type> to Matcher<QualType> + return unconditionalConvertTo<Type>(); + } + return unconditionalConvertTo<QualType>(); +} + +/// \brief Finds the first node in a range that matches the given matcher. +template <typename MatcherT, typename IteratorT> +bool matchesFirstInRange(const MatcherT &Matcher, IteratorT Start, + IteratorT End, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) { + for (IteratorT I = Start; I != End; ++I) { + BoundNodesTreeBuilder Result(*Builder); + if (Matcher.matches(*I, Finder, &Result)) { + *Builder = Result; + return true; + } + } + return false; +} + +/// \brief Finds the first node in a pointer range that matches the given +/// matcher. +template <typename MatcherT, typename IteratorT> +bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start, + IteratorT End, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) { + for (IteratorT I = Start; I != End; ++I) { + BoundNodesTreeBuilder Result(*Builder); + if (Matcher.matches(**I, Finder, &Result)) { + *Builder = Result; + return true; + } + } + return false; +} + /// \brief Metafunction to determine if type T has a member called getDecl. template <typename T> struct has_getDecl { struct Default { int getDecl; }; @@ -632,6 +802,94 @@ protected: AncestorMatchMode MatchMode) = 0; }; +/// \brief A type-list implementation. +/// +/// A list is declared as a tree of type list nodes, where the leafs are the +/// types. +/// However, it is used as a "linked list" of types, by using the ::head and +/// ::tail typedefs. +/// Each node supports up to 4 children (instead of just 2) to reduce the +/// nesting required by large lists. +template <typename T1 = void, typename T2 = void, typename T3 = void, + typename T4 = void> +struct TypeList { + /// \brief Implementation detail. Combined with the specializations below, + /// this typedef allows for flattening of nested structures. + typedef TypeList<T1, T2, T3, T4> self; + + /// \brief The first type on the list. + typedef T1 head; + + /// \brief A sub list with the tail. ie everything but the head. + /// + /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the + /// end of the list. + typedef typename TypeList<T2, T3, T4>::self tail; +}; + +/// \brief Template specialization to allow nested lists. +/// +/// First element is a typelist. Pop its first element. +template <typename Sub1, typename Sub2, typename Sub3, typename Sub4, + typename T2, typename T3, typename T4> +struct TypeList<TypeList<Sub1, Sub2, Sub3, Sub4>, T2, T3, + T4> : public TypeList<Sub1, + typename TypeList<Sub2, Sub3, Sub4>::self, + typename TypeList<T2, T3, T4>::self> {}; + +/// \brief Template specialization to allow nested lists. +/// +/// First element is an empty typelist. Skip it. +template <typename T2, typename T3, typename T4> +struct TypeList<TypeList<>, T2, T3, T4> : public TypeList<T2, T3, T4> { +}; + +/// \brief The empty type list. +typedef TypeList<> EmptyTypeList; + +/// \brief Helper meta-function to determine if some type \c T is present or +/// a parent type in the list. +template <typename AnyTypeList, typename T> +struct TypeListContainsSuperOf { + static const bool value = + llvm::is_base_of<typename AnyTypeList::head, T>::value || + TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value; +}; +template <typename T> +struct TypeListContainsSuperOf<EmptyTypeList, T> { + static const bool value = false; +}; + +/// \brief A "type list" that contains all types. +/// +/// Useful for matchers like \c anything and \c unless. +typedef TypeList< + TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc>, + TypeList<QualType, Type, TypeLoc, CXXCtorInitializer> > AllNodeBaseTypes; + +/// \brief Helper meta-function to extract the argument out of a function of +/// type void(Arg). +/// +/// See AST_POLYMORPHIC_SUPPORTED_TYPES_* for details. +template <class T> struct ExtractFunctionArgMeta; +template <class T> struct ExtractFunctionArgMeta<void(T)> { + typedef T type; +}; + +/// \brief Default type lists for ArgumentAdaptingMatcher matchers. +typedef AllNodeBaseTypes AdaptativeDefaultFromTypes; +typedef TypeList<TypeList<Decl, Stmt, NestedNameSpecifier>, + TypeList<NestedNameSpecifierLoc, TypeLoc, QualType> > +AdaptativeDefaultToTypes; + +/// \brief All types that are supported by HasDeclarationMatcher above. +typedef TypeList<TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType>, + TypeList<InjectedClassNameType, LabelStmt, MemberExpr>, + TypeList<QualType, RecordType, TagType>, + TypeList<TemplateSpecializationType, TemplateTypeParmType, + TypedefType, UnresolvedUsingType> > +HasDeclarationSupportedTypes; + /// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by /// "adapting" a \c To into a \c T. /// @@ -646,19 +904,33 @@ protected: /// If a matcher does not need knowledge about the inner type, prefer to use /// PolymorphicMatcherWithParam1. template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, - typename T> -class ArgumentAdaptingMatcher { -public: - explicit ArgumentAdaptingMatcher(const Matcher<T> &InnerMatcher) - : InnerMatcher(InnerMatcher) {} + typename FromTypes = AdaptativeDefaultFromTypes, + typename ToTypes = AdaptativeDefaultToTypes> +struct ArgumentAdaptingMatcherFunc { + template <typename T> class Adaptor { + public: + explicit Adaptor(const Matcher<T> &InnerMatcher) + : InnerMatcher(InnerMatcher) {} - template <typename To> - operator Matcher<To>() const { - return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher)); + typedef ToTypes ReturnTypes; + + template <typename To> operator Matcher<To>() const { + return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher)); + } + + private: + const Matcher<T> InnerMatcher; + }; + + template <typename T> + static Adaptor<T> create(const Matcher<T> &InnerMatcher) { + return Adaptor<T>(InnerMatcher); } -private: - const Matcher<T> InnerMatcher; + template <typename T> + Adaptor<T> operator()(const Matcher<T> &InnerMatcher) const { + return create(InnerMatcher); + } }; /// \brief A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be @@ -673,24 +945,33 @@ private: /// - PolymorphicMatcherWithParam1<ValueEqualsMatcher, int>(42) /// creates an object that can be used as a Matcher<T> for any type T /// where a ValueEqualsMatcher<T, int>(42) can be constructed. -template <template <typename T> class MatcherT> +template <template <typename T> class MatcherT, + typename ReturnTypesF = void(AllNodeBaseTypes)> class PolymorphicMatcherWithParam0 { public: + typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; template <typename T> operator Matcher<T>() const { + TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value), + right_polymorphic_conversion); return Matcher<T>(new MatcherT<T>()); } }; template <template <typename T, typename P1> class MatcherT, - typename P1> + typename P1, + typename ReturnTypesF = void(AllNodeBaseTypes)> class PolymorphicMatcherWithParam1 { public: explicit PolymorphicMatcherWithParam1(const P1 &Param1) : Param1(Param1) {} + typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; + template <typename T> operator Matcher<T>() const { + TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value), + right_polymorphic_conversion); return Matcher<T>(new MatcherT<T, P1>(Param1)); } @@ -699,14 +980,19 @@ private: }; template <template <typename T, typename P1, typename P2> class MatcherT, - typename P1, typename P2> + typename P1, typename P2, + typename ReturnTypesF = void(AllNodeBaseTypes)> class PolymorphicMatcherWithParam2 { public: PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2) : Param1(Param1), Param2(Param2) {} + typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; + template <typename T> operator Matcher<T>() const { + TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value), + right_polymorphic_conversion); return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2)); } @@ -737,27 +1023,6 @@ public: } }; -/// \brief Provides a MatcherInterface<T> for a Matcher<To> that matches if T is -/// dyn_cast'able into To and the given Matcher<To> matches on the dyn_cast'ed -/// node. -template <typename T, typename To> -class DynCastMatcher : public MatcherInterface<T> { -public: - explicit DynCastMatcher(const Matcher<To> &InnerMatcher) - : InnerMatcher(InnerMatcher) {} - - virtual bool matches(const T &Node, - ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { - const To *InnerMatchValue = dyn_cast<To>(&Node); - return InnerMatchValue != NULL && - InnerMatcher.matches(*InnerMatchValue, Finder, Builder); - } - -private: - const Matcher<To> InnerMatcher; -}; - /// \brief Matcher<T> that wraps an inner Matcher<T> and binds the matched node /// to an ID if the inner matcher matches on the node. template <typename T> @@ -790,7 +1055,8 @@ private: template <typename T> class BindableMatcher : public Matcher<T> { public: - BindableMatcher(MatcherInterface<T> *Implementation) + explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {} + explicit BindableMatcher(MatcherInterface<T> *Implementation) : Matcher<T>(Implementation) {} /// \brief Returns a matcher that will bind the matched node on a match. @@ -867,108 +1133,172 @@ public: virtual bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - return !InnerMatcher.matches(Node, Finder, Builder); + // The 'unless' matcher will always discard the result: + // If the inner matcher doesn't match, unless returns true, + // but the inner matcher cannot have bound anything. + // If the inner matcher matches, the result is false, and + // any possible binding will be discarded. + // We still need to hand in all the bound nodes up to this + // point so the inner matcher can depend on bound nodes, + // and we need to actively discard the bound nodes, otherwise + // the inner matcher will reset the bound nodes if it doesn't + // match, but this would be inversed by 'unless'. + BoundNodesTreeBuilder Discard(*Builder); + return !InnerMatcher.matches(Node, Finder, &Discard); } private: const Matcher<T> InnerMatcher; }; -/// \brief Matches nodes of type T for which both provided matchers match. -/// -/// Type arguments MatcherT1 and MatcherT2 are required by -/// PolymorphicMatcherWithParam2 but not actually used. They will -/// always be instantiated with types convertible to Matcher<T>. -template <typename T, typename MatcherT1, typename MatcherT2> -class AllOfMatcher : public MatcherInterface<T> { +/// \brief VariadicOperatorMatcher related types. +/// @{ + +/// \brief Function signature for any variadic operator. It takes the inner +/// matchers as an array of DynTypedMatcher. +typedef bool (*VariadicOperatorFunction)( + const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers); + +/// \brief \c MatcherInterface<T> implementation for an variadic operator. +template <typename T> +class VariadicOperatorMatcherInterface : public MatcherInterface<T> { public: - AllOfMatcher(const Matcher<T> &InnerMatcher1, const Matcher<T> &InnerMatcher2) - : InnerMatcher1(InnerMatcher1), InnerMatcher2(InnerMatcher2) {} + VariadicOperatorMatcherInterface(VariadicOperatorFunction Func, + ArrayRef<const Matcher<T> *> InputMatchers) + : Func(Func) { + for (size_t i = 0, e = InputMatchers.size(); i != e; ++i) { + InnerMatchers.push_back(*InputMatchers[i]); + } + } - virtual bool matches(const T &Node, - ASTMatchFinder *Finder, + virtual bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - return InnerMatcher1.matches(Node, Finder, Builder) && - InnerMatcher2.matches(Node, Finder, Builder); + return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder, + InnerMatchers); } private: - const Matcher<T> InnerMatcher1; - const Matcher<T> InnerMatcher2; + const VariadicOperatorFunction Func; + std::vector<DynTypedMatcher> InnerMatchers; }; -/// \brief Matches nodes of type T for which at least one of the two provided -/// matchers matches. +/// \brief "No argument" placeholder to use as template paratemers. +struct VariadicOperatorNoArg {}; + +/// \brief Polymorphic matcher object that uses a \c VariadicOperatorFunction +/// operator. /// -/// Type arguments MatcherT1 and MatcherT2 are -/// required by PolymorphicMatcherWithParam2 but not actually -/// used. They will always be instantiated with types convertible to -/// Matcher<T>. -template <typename T, typename MatcherT1, typename MatcherT2> -class EachOfMatcher : public MatcherInterface<T> { +/// Input matchers can have any type (including other polymorphic matcher +/// types), and the actual Matcher<T> is generated on demand with an implicit +/// coversion operator. +template <typename P1, typename P2, + typename P3 = VariadicOperatorNoArg, + typename P4 = VariadicOperatorNoArg, + typename P5 = VariadicOperatorNoArg> +class VariadicOperatorMatcher { public: - EachOfMatcher(const Matcher<T> &InnerMatcher1, - const Matcher<T> &InnerMatcher2) - : InnerMatcher1(InnerMatcher1), InnerMatcher2(InnerMatcher2) { + VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1, + const P2 &Param2, + const P3 &Param3 = VariadicOperatorNoArg(), + const P4 &Param4 = VariadicOperatorNoArg(), + const P5 &Param5 = VariadicOperatorNoArg()) + : Func(Func), Param1(Param1), Param2(Param2), Param3(Param3), + Param4(Param4), Param5(Param5) {} + + template <typename T> operator Matcher<T>() const { + Matcher<T> *Array[5]; + size_t Size = 0; + + addMatcher<T>(Param1, Array, Size); + addMatcher<T>(Param2, Array, Size); + addMatcher<T>(Param3, Array, Size); + addMatcher<T>(Param4, Array, Size); + addMatcher<T>(Param5, Array, Size); + Matcher<T> Result(new VariadicOperatorMatcherInterface<T>( + Func, ArrayRef<const Matcher<T> *>(Array, Size))); + for (size_t i = 0, e = Size; i != e; ++i) delete Array[i]; + return Result; } - virtual bool matches(const T &Node, ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { - BoundNodesTreeBuilder Builder1; - bool Matched1 = InnerMatcher1.matches(Node, Finder, &Builder1); - if (Matched1) - Builder->addMatch(Builder1.build()); - - BoundNodesTreeBuilder Builder2; - bool Matched2 = InnerMatcher2.matches(Node, Finder, &Builder2); - if (Matched2) - Builder->addMatch(Builder2.build()); - - return Matched1 || Matched2; +private: + template <typename T> + static void addMatcher(const Matcher<T> &M, Matcher<T> **Array, + size_t &Size) { + Array[Size++] = new Matcher<T>(M); } -private: - const Matcher<T> InnerMatcher1; - const Matcher<T> InnerMatcher2; + /// \brief Overload to ignore \c VariadicOperatorNoArg arguments. + template <typename T> + static void addMatcher(VariadicOperatorNoArg, Matcher<T> **Array, + size_t &Size) {} + + const VariadicOperatorFunction Func; + const P1 Param1; + const P2 Param2; + const P3 Param3; + const P4 Param4; + const P5 Param5; }; -/// \brief Matches nodes of type T for which at least one of the two provided -/// matchers matches. +/// \brief Overloaded function object to generate VariadicOperatorMatcher +/// objects from arbitrary matchers. /// -/// Type arguments MatcherT1 and MatcherT2 are -/// required by PolymorphicMatcherWithParam2 but not actually -/// used. They will always be instantiated with types convertible to -/// Matcher<T>. -template <typename T, typename MatcherT1, typename MatcherT2> -class AnyOfMatcher : public MatcherInterface<T> { -public: - AnyOfMatcher(const Matcher<T> &InnerMatcher1, const Matcher<T> &InnerMatcher2) - : InnerMatcher1(InnerMatcher1), InnerMatcher2(InnerMatcher2) {} +/// It supports 2-5 argument overloaded operator(). More can be added if needed. +struct VariadicOperatorMatcherFunc { + VariadicOperatorFunction Func; - virtual bool matches(const T &Node, - ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder) const { - return InnerMatcher1.matches(Node, Finder, Builder) || - InnerMatcher2.matches(Node, Finder, Builder); + template <typename M1, typename M2> + VariadicOperatorMatcher<M1, M2> operator()(const M1 &P1, const M2 &P2) const { + return VariadicOperatorMatcher<M1, M2>(Func, P1, P2); + } + template <typename M1, typename M2, typename M3> + VariadicOperatorMatcher<M1, M2, M3> operator()(const M1 &P1, const M2 &P2, + const M3 &P3) const { + return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3); + } + template <typename M1, typename M2, typename M3, typename M4> + VariadicOperatorMatcher<M1, M2, M3, M4> + operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const { + return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4); + } + template <typename M1, typename M2, typename M3, typename M4, typename M5> + VariadicOperatorMatcher<M1, M2, M3, M4, M5> + operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, + const M5 &P5) const { + return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4, + P5); } - -private: - const Matcher<T> InnerMatcher1; - const Matcher<T> InnerMatcher2; }; +/// @} + +/// \brief Matches nodes for which all provided matchers match. +bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, + ArrayRef<DynTypedMatcher> InnerMatchers); + +/// \brief Matches nodes for which at least one of the provided matchers +/// matches, but doesn't stop at the first match. +bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, + ArrayRef<DynTypedMatcher> InnerMatchers); + +/// \brief Matches nodes for which at least one of the provided matchers +/// matches. +bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, + ArrayRef<DynTypedMatcher> InnerMatchers); + /// \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); + return BindableMatcher<T>(new VariadicOperatorMatcherInterface<T>( + AllOfVariadicOperator, InnerMatchers)); } /// \brief Creates a Matcher<T> that matches if @@ -980,8 +1310,8 @@ BindableMatcher<T> makeAllOfComposite( template<typename T, typename InnerT> BindableMatcher<T> makeDynCastAllOfComposite( ArrayRef<const Matcher<InnerT> *> InnerMatchers) { - return BindableMatcher<T>(new DynCastMatcher<T, InnerT>( - makeAllOfComposite(InnerMatchers))); + return BindableMatcher<T>(DynTypedMatcher(makeAllOfComposite(InnerMatchers)) + .unconditionalConvertTo<T>()); } /// \brief Matches nodes of type T that have at least one descendant node of @@ -1233,9 +1563,53 @@ private: TypeLoc (T::*TraverseFunction)() const; }; -template <typename T, typename InnerT> -T makeTypeAllOfComposite(ArrayRef<const Matcher<InnerT> *> InnerMatchers) { - return T(makeAllOfComposite<InnerT>(InnerMatchers)); +/// \brief Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where +/// \c OuterT is any type that is supported by \c Getter. +/// +/// \code Getter<OuterT>::value() \endcode returns a +/// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT +/// object into a \c InnerT +template <typename InnerTBase, + template <typename OuterT> class Getter, + template <typename OuterT> class MatcherImpl, + typename ReturnTypesF> +class TypeTraversePolymorphicMatcher { +private: + typedef TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, + ReturnTypesF> Self; + static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers); + +public: + typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; + + explicit TypeTraversePolymorphicMatcher( + ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) + : InnerMatcher(makeAllOfComposite(InnerMatchers)) {} + + template <typename OuterT> operator Matcher<OuterT>() const { + return Matcher<OuterT>( + new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value())); + } + + struct Func : public llvm::VariadicFunction<Self, Matcher<InnerTBase>, + &Self::create> { + Func() {} + }; + +private: + const Matcher<InnerTBase> InnerMatcher; +}; + +// Define the create() method out of line to silence a GCC warning about +// the struct "Func" having greater visibility than its base, which comes from +// using the flag -fvisibility-inlines-hidden. +template <typename InnerTBase, template <typename OuterT> class Getter, + template <typename OuterT> class MatcherImpl, typename ReturnTypesF> +TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF> +TypeTraversePolymorphicMatcher< + InnerTBase, Getter, MatcherImpl, + ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) { + return Self(InnerMatchers); } } // end namespace internal diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h index f5ca26b..b5d5303 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -49,23 +49,19 @@ /// /// The code should return true if 'Node' matches. #define AST_MATCHER(Type, DefineMatcher) \ - AST_MATCHER_OVERLOAD(Type, DefineMatcher, 0) - -#define AST_MATCHER_OVERLOAD(Type, DefineMatcher, OverloadId) \ namespace internal { \ - class matcher_##DefineMatcher##OverloadId##Matcher \ - : public MatcherInterface<Type> { \ + class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> { \ public: \ - explicit matcher_##DefineMatcher##OverloadId##Matcher() {} \ + explicit matcher_##DefineMatcher##Matcher() {} \ virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ }; \ } \ inline internal::Matcher<Type> DefineMatcher() { \ return internal::makeMatcher( \ - new internal::matcher_##DefineMatcher##OverloadId##Matcher()); \ + new internal::matcher_##DefineMatcher##Matcher()); \ } \ - inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ + inline bool internal::matcher_##DefineMatcher##Matcher::matches( \ const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const @@ -93,10 +89,10 @@ public: \ explicit matcher_##DefineMatcher##OverloadId##Matcher( \ const ParamType &A##Param) \ - : Param(A##Param) { \ - } \ + : Param(A##Param) {} \ virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ + \ private: \ const ParamType Param; \ }; \ @@ -105,6 +101,8 @@ return internal::makeMatcher( \ new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \ } \ + typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)( \ + const ParamType &Param); \ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const @@ -136,53 +134,70 @@ public: \ matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \ const ParamType2 &A##Param2) \ - : Param1(A##Param1), Param2(A##Param2) { \ - } \ + : Param1(A##Param1), Param2(A##Param2) {} \ virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ + \ private: \ const ParamType1 Param1; \ const ParamType2 Param2; \ }; \ } \ - inline internal::Matcher<Type> \ - DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \ + inline internal::Matcher<Type> DefineMatcher(const ParamType1 &Param1, \ + const ParamType2 &Param2) { \ return internal::makeMatcher( \ new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \ Param2)); \ } \ + typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)( \ + const ParamType1 &Param1, const ParamType2 &Param2); \ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const +/// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER* +/// macros. +/// +/// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it +/// will look at that as two arguments. However, you can pass +/// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis. +/// The \c PolymorphicMatcherWithParam* classes will unpack the function type to +/// extract the TypeList object. +#define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>) +#define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2) \ + void(internal::TypeList<t1, t2>) +#define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3) \ + void(internal::TypeList<t1, t2, t3>) +#define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4) \ + void(internal::TypeList<t1, t2, t3, t4>) +#define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5) \ + void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >) + /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } /// defines a single-parameter function named DefineMatcher() that is /// polymorphic in the return type. /// /// The variables are the same as for AST_MATCHER, but NodeType will be deduced /// from the calling context. -#define AST_POLYMORPHIC_MATCHER(DefineMatcher) \ - AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, 0) - -#define AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, OverloadId) \ +#define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \ namespace internal { \ template <typename NodeType> \ - class matcher_##DefineMatcher##OverloadId##Matcher \ - : public MatcherInterface<NodeType> { \ + class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \ public: \ virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ }; \ } \ inline internal::PolymorphicMatcherWithParam0< \ - internal::matcher_##DefineMatcher##OverloadId##Matcher> DefineMatcher() {\ + internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \ + DefineMatcher() { \ return internal::PolymorphicMatcherWithParam0< \ - internal::matcher_##DefineMatcher##OverloadId##Matcher>(); \ + internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \ } \ template <typename NodeType> \ - bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ - NodeType>::matches(const NodeType &Node, ASTMatchFinder *Finder, \ - BoundNodesTreeBuilder *Builder) const + bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \ + const NodeType &Node, ASTMatchFinder *Finder, \ + BoundNodesTreeBuilder *Builder) const /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... } /// defines a single-parameter function named DefineMatcher() that is @@ -193,11 +208,13 @@ /// of the matcher Matcher<NodeType> returned by the function matcher(). /// /// FIXME: Pull out common code with above macro? -#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) \ - AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, 0) +#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \ + Param) \ + AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \ + Param, 0) -#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, \ - OverloadId) \ +#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \ + ParamType, Param, OverloadId) \ namespace internal { \ template <typename NodeType, typename ParamT> \ class matcher_##DefineMatcher##OverloadId##Matcher \ @@ -205,21 +222,25 @@ public: \ explicit matcher_##DefineMatcher##OverloadId##Matcher( \ const ParamType &A##Param) \ - : Param(A##Param) { \ - } \ + : Param(A##Param) {} \ virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ + \ private: \ const ParamType Param; \ }; \ } \ inline internal::PolymorphicMatcherWithParam1< \ - internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType> \ - DefineMatcher(const ParamType &Param) { \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ + ReturnTypesF> DefineMatcher(const ParamType &Param) { \ return internal::PolymorphicMatcherWithParam1< \ - internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType>( \ - Param); \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ + ReturnTypesF>(Param); \ } \ + typedef internal::PolymorphicMatcherWithParam1< \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ + ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ + const ParamType &Param); \ template <typename NodeType, typename ParamT> \ bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \ @@ -233,13 +254,14 @@ /// The variables are the same as for AST_MATCHER_P2, with the /// addition of NodeType, which specifies the node type of the matcher /// Matcher<NodeType> returned by the function DefineMatcher(). -#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ParamType1, Param1, \ - ParamType2, Param2) \ - AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \ - ParamType2, Param2, 0) +#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \ + Param1, ParamType2, Param2) \ + AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \ + Param1, ParamType2, Param2, 0) -#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \ - ParamType2, Param2, OverloadId) \ +#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \ + ParamType1, Param1, ParamType2, \ + Param2, OverloadId) \ namespace internal { \ template <typename NodeType, typename ParamT1, typename ParamT2> \ class matcher_##DefineMatcher##OverloadId##Matcher \ @@ -247,10 +269,10 @@ public: \ matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \ const ParamType2 &A##Param2) \ - : Param1(A##Param1), Param2(A##Param2) { \ - } \ + : Param1(A##Param1), Param2(A##Param2) {} \ virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ + \ private: \ const ParamType1 Param1; \ const ParamType2 Param2; \ @@ -258,12 +280,16 @@ } \ inline internal::PolymorphicMatcherWithParam2< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ - ParamType2> \ - DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \ + ParamType2, ReturnTypesF> DefineMatcher(const ParamType1 &Param1, \ + const ParamType2 &Param2) { \ return internal::PolymorphicMatcherWithParam2< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ - ParamType2>(Param1, Param2); \ + ParamType2, ReturnTypesF>(Param1, Param2); \ } \ + typedef internal::PolymorphicMatcherWithParam2< \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ + ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ + const ParamType1 &Param1, const ParamType2 &Param2); \ template <typename NodeType, typename ParamT1, typename ParamT2> \ bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ NodeType, ParamT1, ParamT2>::matches( \ @@ -282,64 +308,29 @@ /// to another. /// /// For a specific \c SpecificType, the traversal is done using -/// \c SpecificType::FunctionName. The existance of such a function determines +/// \c SpecificType::FunctionName. The existence 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() { \ - } \ +#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ + namespace internal { \ + template <typename T> struct TypeMatcher##MatcherName##Getter { \ + static QualType (T::*value())() const { return &T::FunctionName; } \ + }; \ } \ - ; \ - const Variadic##MatcherName##TypeTraverseMatcher MatcherName + const internal::TypeTraversePolymorphicMatcher< \ + QualType, internal::TypeMatcher##MatcherName##Getter, \ + internal::TypeTraverseMatcher, ReturnTypesF>::Func 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() { \ - } \ +#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ + namespace internal { \ + template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ + static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ + }; \ } \ - ; \ - const Variadic##MatcherName##TypeLocTraverseMatcher MatcherName##Loc; \ - AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type) + const internal::TypeTraversePolymorphicMatcher< \ + TypeLoc, internal::TypeLocMatcher##MatcherName##Getter, \ + internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc; \ + AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) #endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h new file mode 100644 index 0000000..aec0c0e --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h @@ -0,0 +1,185 @@ +//===--- Diagnostics.h - Helper class for error diagnostics -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Diagnostics class to manage error messages. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H +#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H + +#include <string> +#include <vector> + +#include "clang/ASTMatchers/Dynamic/VariantValue.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { +namespace ast_matchers { +namespace dynamic { + +struct SourceLocation { + SourceLocation() : Line(), Column() {} + unsigned Line; + unsigned Column; +}; + +struct SourceRange { + SourceLocation Start; + SourceLocation End; +}; + +/// \brief A VariantValue instance annotated with its parser context. +struct ParserValue { + ParserValue() : Text(), Range(), Value() {} + StringRef Text; + SourceRange Range; + VariantValue Value; +}; + +/// \brief Helper class to manage error messages. +class Diagnostics { +public: + /// \brief Parser context types. + enum ContextType { + CT_MatcherArg = 0, + CT_MatcherConstruct = 1 + }; + + /// \brief All errors from the system. + enum ErrorType { + ET_None = 0, + + ET_RegistryNotFound = 1, + ET_RegistryWrongArgCount = 2, + ET_RegistryWrongArgType = 3, + ET_RegistryNotBindable = 4, + ET_RegistryAmbiguousOverload = 5, + + ET_ParserStringError = 100, + ET_ParserNoOpenParen = 101, + ET_ParserNoCloseParen = 102, + ET_ParserNoComma = 103, + ET_ParserNoCode = 104, + ET_ParserNotAMatcher = 105, + ET_ParserInvalidToken = 106, + ET_ParserMalformedBindExpr = 107, + ET_ParserTrailingCode = 108, + ET_ParserUnsignedError = 109, + ET_ParserOverloadedType = 110 + }; + + /// \brief Helper stream class. + class ArgStream { + public: + ArgStream(std::vector<std::string> *Out) : Out(Out) {} + template <class T> ArgStream &operator<<(const T &Arg) { + return operator<<(Twine(Arg)); + } + ArgStream &operator<<(const Twine &Arg); + + private: + std::vector<std::string> *Out; + }; + + /// \brief Class defining a parser context. + /// + /// Used by the parser to specify (possibly recursive) contexts where the + /// parsing/construction can fail. Any error triggered within a context will + /// keep information about the context chain. + /// This class should be used as a RAII instance in the stack. + struct Context { + public: + /// \brief About to call the constructor for a matcher. + enum ConstructMatcherEnum { ConstructMatcher }; + Context(ConstructMatcherEnum, Diagnostics *Error, StringRef MatcherName, + const SourceRange &MatcherRange); + /// \brief About to recurse into parsing one argument for a matcher. + enum MatcherArgEnum { MatcherArg }; + Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName, + const SourceRange &MatcherRange, unsigned ArgNumber); + ~Context(); + + private: + Diagnostics *const Error; + }; + + /// \brief Context for overloaded matcher construction. + /// + /// This context will take care of merging all errors that happen within it + /// as "candidate" overloads for the same matcher. + struct OverloadContext { + public: + OverloadContext(Diagnostics* Error); + ~OverloadContext(); + + /// \brief Revert all errors that happened within this context. + void revertErrors(); + + private: + Diagnostics *const Error; + unsigned BeginIndex; + }; + + /// \brief Add an error to the diagnostics. + /// + /// All the context information will be kept on the error message. + /// \return a helper class to allow the caller to pass the arguments for the + /// error message, using the << operator. + ArgStream addError(const SourceRange &Range, ErrorType Error); + + /// \brief Information stored for one frame of the context. + struct ContextFrame { + ContextType Type; + SourceRange Range; + std::vector<std::string> Args; + }; + + /// \brief Information stored for each error found. + struct ErrorContent { + std::vector<ContextFrame> ContextStack; + struct Message { + SourceRange Range; + ErrorType Type; + std::vector<std::string> Args; + }; + std::vector<Message> Messages; + }; + ArrayRef<ErrorContent> errors() const { return Errors; } + + /// \brief Returns a simple string representation of each error. + /// + /// Each error only shows the error message without any context. + void printToStream(llvm::raw_ostream &OS) const; + std::string toString() const; + + /// \brief Returns the full string representation of each error. + /// + /// Each error message contains the full context. + void printToStreamFull(llvm::raw_ostream &OS) const; + std::string toStringFull() const; + +private: + /// \brief Helper function used by the constructors of ContextFrame. + ArgStream pushContextFrame(ContextType Type, SourceRange Range); + + std::vector<ContextFrame> ContextStack; + std::vector<ErrorContent> Errors; +}; + +} // namespace dynamic +} // namespace ast_matchers +} // namespace clang + +#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Parser.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Parser.h new file mode 100644 index 0000000..bb6ac76 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Parser.h @@ -0,0 +1,151 @@ +//===--- Parser.h - Matcher expression parser -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Simple matcher expression parser. +/// +/// The parser understands matcher expressions of the form: +/// MatcherName(Arg0, Arg1, ..., ArgN) +/// as well as simple types like strings. +/// The parser does not know how to process the matchers. It delegates this task +/// to a Sema object received as an argument. +/// +/// \code +/// Grammar for the expressions supported: +/// <Expression> := <Literal> | <MatcherExpression> +/// <Literal> := <StringLiteral> | <Unsigned> +/// <StringLiteral> := "quoted string" +/// <Unsigned> := [0-9]+ +/// <MatcherExpression> := <MatcherName>(<ArgumentList>) | +/// <MatcherName>(<ArgumentList>).bind(<StringLiteral>) +/// <MatcherName> := [a-zA-Z]+ +/// <ArgumentList> := <Expression> | <Expression>,<ArgumentList> +/// \endcode +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H +#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H + +#include "clang/ASTMatchers/Dynamic/Diagnostics.h" +#include "clang/ASTMatchers/Dynamic/VariantValue.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { +namespace ast_matchers { +namespace dynamic { + +/// \brief Matcher expression parser. +class Parser { +public: + /// \brief Interface to connect the parser with the registry and more. + /// + /// The parser uses the Sema instance passed into + /// parseMatcherExpression() to handle all matcher tokens. The simplest + /// processor implementation would simply call into the registry to create + /// the matchers. + /// However, a more complex processor might decide to intercept the matcher + /// creation and do some extra work. For example, it could apply some + /// transformation to the matcher by adding some id() nodes, or could detect + /// specific matcher nodes for more efficient lookup. + class Sema { + public: + virtual ~Sema(); + + /// \brief Process a matcher expression. + /// + /// All the arguments passed here have already been processed. + /// + /// \param MatcherName The matcher name found by the parser. + /// + /// \param NameRange The location of the name in the matcher source. + /// Useful for error reporting. + /// + /// \param BindID The ID to use to bind the matcher, or a null \c StringRef + /// if no ID is specified. + /// + /// \param Args The argument list for the matcher. + /// + /// \return The matcher objects constructed by the processor, or a null + /// matcher if an error occurred. In that case, \c Error will contain a + /// description of the error. + virtual VariantMatcher actOnMatcherExpression(StringRef MatcherName, + const SourceRange &NameRange, + StringRef BindID, + ArrayRef<ParserValue> Args, + Diagnostics *Error) = 0; + }; + + /// \brief Parse a matcher expression, creating matchers from the registry. + /// + /// This overload creates matchers calling directly into the registry. If the + /// caller needs more control over how the matchers are created, then it can + /// use the overload below that takes a Sema. + /// + /// \param MatcherCode The matcher expression to parse. + /// + /// \return The matcher object constructed, or an empty Optional if an error + /// occurred. + /// In that case, \c Error will contain a description of the error. + /// The caller takes ownership of the DynTypedMatcher object returned. + static llvm::Optional<DynTypedMatcher> + parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error); + + /// \brief Parse a matcher expression. + /// + /// \param MatcherCode The matcher expression to parse. + /// + /// \param S The Sema instance that will help the parser + /// construct the matchers. + /// \return The matcher object constructed by the processor, or an empty + /// Optional if an error occurred. In that case, \c Error will contain a + /// description of the error. + /// The caller takes ownership of the DynTypedMatcher object returned. + static llvm::Optional<DynTypedMatcher> + parseMatcherExpression(StringRef MatcherCode, Sema *S, Diagnostics *Error); + + /// \brief Parse an expression, creating matchers from the registry. + /// + /// Parses any expression supported by this parser. In general, the + /// \c parseMatcherExpression function is a better approach to get a matcher + /// object. + static bool parseExpression(StringRef Code, VariantValue *Value, + Diagnostics *Error); + + /// \brief Parse an expression. + /// + /// Parses any expression supported by this parser. In general, the + /// \c parseMatcherExpression function is a better approach to get a matcher + /// object. + static bool parseExpression(StringRef Code, Sema *S, + VariantValue *Value, Diagnostics *Error); + +private: + class CodeTokenizer; + struct TokenInfo; + + Parser(CodeTokenizer *Tokenizer, Sema *S, + Diagnostics *Error); + + bool parseExpressionImpl(VariantValue *Value); + bool parseMatcherExpressionImpl(VariantValue *Value); + + CodeTokenizer *const Tokenizer; + Sema *const S; + Diagnostics *const Error; +}; + +} // namespace dynamic +} // namespace ast_matchers +} // namespace clang + +#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Registry.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Registry.h new file mode 100644 index 0000000..c113c14 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Registry.h @@ -0,0 +1,75 @@ +//===--- Registry.h - Matcher registry -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Registry of all known matchers. +/// +/// The registry provides a generic interface to construct any matcher by name. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H +#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H + +#include "clang/ASTMatchers/Dynamic/Diagnostics.h" +#include "clang/ASTMatchers/Dynamic/VariantValue.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { +namespace ast_matchers { +namespace dynamic { + +class Registry { +public: + /// \brief Construct a matcher from the registry by name. + /// + /// Consult the registry of known matchers and construct the appropriate + /// matcher by name. + /// + /// \param MatcherName The name of the matcher to instantiate. + /// + /// \param NameRange The location of the name in the matcher source. + /// Useful for error reporting. + /// + /// \param Args The argument list for the matcher. The number and types of the + /// values must be valid for the matcher requested. Otherwise, the function + /// will return an error. + /// + /// \return The matcher object constructed if no error was found. + /// A null matcher if the matcher is not found, or if the number of + /// arguments or argument types do not match the signature. + /// In that case \c Error will contain the description of the error. + static VariantMatcher constructMatcher(StringRef MatcherName, + const SourceRange &NameRange, + ArrayRef<ParserValue> Args, + Diagnostics *Error); + + /// \brief Construct a matcher from the registry and bind it. + /// + /// Similar the \c constructMatcher() above, but it then tries to bind the + /// matcher to the specified \c BindID. + /// If the matcher is not bindable, it sets an error in \c Error and returns + /// a null matcher. + static VariantMatcher constructBoundMatcher(StringRef MatcherName, + const SourceRange &NameRange, + StringRef BindID, + ArrayRef<ParserValue> Args, + Diagnostics *Error); + +private: + Registry() LLVM_DELETED_FUNCTION; +}; + +} // namespace dynamic +} // namespace ast_matchers +} // namespace clang + +#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h new file mode 100644 index 0000000..b9bc017 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -0,0 +1,261 @@ +//===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/ +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Polymorphic value type. +/// +/// Supports all the types required for dynamic Matcher construction. +/// Used by the registry to construct matchers in a generic way. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H +#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H + +#include <vector> + +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersInternal.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/type_traits.h" + +namespace clang { +namespace ast_matchers { +namespace dynamic { + +using ast_matchers::internal::DynTypedMatcher; + +/// \brief A variant matcher object. +/// +/// The purpose of this object is to abstract simple and polymorphic matchers +/// into a single object type. +/// Polymorphic matchers might be implemented as a list of all the possible +/// overloads of the matcher. \c VariantMatcher knows how to select the +/// appropriate overload when needed. +/// To get a real matcher object out of a \c VariantMatcher you can do: +/// - getSingleMatcher() which returns a matcher, only if it is not ambiguous +/// to decide which matcher to return. Eg. it contains only a single +/// matcher, or a polymorphic one with only one overload. +/// - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if +/// the underlying matcher(s) can unambiguously return a Matcher<T>. +class VariantMatcher { + /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher. + class MatcherOps { + public: + virtual ~MatcherOps(); + virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const = 0; + virtual void constructFrom(const DynTypedMatcher &Matcher) = 0; + virtual void constructVariadicOperator( + ast_matchers::internal::VariadicOperatorFunction Func, + ArrayRef<VariantMatcher> InnerMatchers) = 0; + }; + + /// \brief Payload interface to be specialized by each matcher type. + /// + /// It follows a similar interface as VariantMatcher itself. + class Payload : public RefCountedBaseVPTR { + public: + virtual ~Payload(); + virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0; + virtual std::string getTypeAsString() const = 0; + virtual void makeTypedMatcher(MatcherOps &Ops) const = 0; + }; + +public: + /// \brief A null matcher. + VariantMatcher(); + + /// \brief Clones the provided matcher. + static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher); + + /// \brief Clones the provided matchers. + /// + /// They should be the result of a polymorphic matcher. + static VariantMatcher PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers); + + /// \brief Creates a 'variadic' operator matcher. + /// + /// It will bind to the appropriate type on getTypedMatcher<T>(). + static VariantMatcher VariadicOperatorMatcher( + ast_matchers::internal::VariadicOperatorFunction Func, + ArrayRef<VariantMatcher> Args); + + /// \brief Makes the matcher the "null" matcher. + void reset(); + + /// \brief Whether the matcher is null. + bool isNull() const { return !Value; } + + /// \brief Return a single matcher, if there is no ambiguity. + /// + /// \returns the matcher, if there is only one matcher. An empty Optional, if + /// the underlying matcher is a polymorphic matcher with more than one + /// representation. + llvm::Optional<DynTypedMatcher> getSingleMatcher() const; + + /// \brief Determines if the contained matcher can be converted to + /// \c Matcher<T>. + /// + /// For the Single case, it returns true if it can be converted to + /// \c Matcher<T>. + /// For the Polymorphic case, it returns true if one, and only one, of the + /// overloads can be converted to \c Matcher<T>. If there are more than one + /// that can, the result would be ambiguous and false is returned. + template <class T> + bool hasTypedMatcher() const { + TypedMatcherOps<T> Ops; + if (Value) Value->makeTypedMatcher(Ops); + return Ops.hasMatcher(); + } + + /// \brief Return this matcher as a \c Matcher<T>. + /// + /// Handles the different types (Single, Polymorphic) accordingly. + /// Asserts that \c hasTypedMatcher<T>() is true. + template <class T> + ast_matchers::internal::Matcher<T> getTypedMatcher() const { + TypedMatcherOps<T> Ops; + Value->makeTypedMatcher(Ops); + assert(Ops.hasMatcher() && "hasTypedMatcher<T>() == false"); + return Ops.matcher(); + } + + /// \brief String representation of the type of the value. + /// + /// If the underlying matcher is a polymorphic one, the string will show all + /// the types. + std::string getTypeAsString() const; + +private: + explicit VariantMatcher(Payload *Value) : Value(Value) {} + + class SinglePayload; + class PolymorphicPayload; + class VariadicOpPayload; + + template <typename T> + class TypedMatcherOps : public MatcherOps { + public: + typedef ast_matchers::internal::Matcher<T> MatcherT; + + virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const { + return Matcher.canConvertTo<T>(); + } + + virtual void constructFrom(const DynTypedMatcher& Matcher) { + Out.reset(new MatcherT(Matcher.convertTo<T>())); + } + + virtual void constructVariadicOperator( + ast_matchers::internal::VariadicOperatorFunction Func, + ArrayRef<VariantMatcher> InnerMatchers) { + const size_t NumArgs = InnerMatchers.size(); + MatcherT **InnerArgs = new MatcherT *[NumArgs](); + bool HasError = false; + for (size_t i = 0; i != NumArgs; ++i) { + // Abort if any of the inner matchers can't be converted to + // Matcher<T>. + if (!InnerMatchers[i].hasTypedMatcher<T>()) { + HasError = true; + break; + } + InnerArgs[i] = new MatcherT(InnerMatchers[i].getTypedMatcher<T>()); + } + if (!HasError) { + Out.reset(new MatcherT( + new ast_matchers::internal::VariadicOperatorMatcherInterface<T>( + Func, ArrayRef<const MatcherT *>(InnerArgs, NumArgs)))); + } + for (size_t i = 0; i != NumArgs; ++i) { + delete InnerArgs[i]; + } + delete[] InnerArgs; + } + + bool hasMatcher() const { return Out.get() != NULL; } + const MatcherT &matcher() const { return *Out; } + + private: + OwningPtr<MatcherT> Out; + }; + + IntrusiveRefCntPtr<const Payload> Value; +}; + +/// \brief Variant value class. +/// +/// Basically, a tagged union with value type semantics. +/// It is used by the registry as the return value and argument type for the +/// matcher factory methods. +/// It can be constructed from any of the supported types. It supports +/// copy/assignment. +/// +/// Supported types: +/// - \c unsigned +/// - \c std::string +/// - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>) +class VariantValue { +public: + VariantValue() : Type(VT_Nothing) {} + + VariantValue(const VariantValue &Other); + ~VariantValue(); + VariantValue &operator=(const VariantValue &Other); + + /// \brief Specific constructors for each supported type. + VariantValue(unsigned Unsigned); + VariantValue(const std::string &String); + VariantValue(const VariantMatcher &Matchers); + + /// \brief Unsigned value functions. + bool isUnsigned() const; + unsigned getUnsigned() const; + void setUnsigned(unsigned Unsigned); + + /// \brief String value functions. + bool isString() const; + const std::string &getString() const; + void setString(const std::string &String); + + /// \brief Matcher value functions. + bool isMatcher() const; + const VariantMatcher &getMatcher() const; + void setMatcher(const VariantMatcher &Matcher); + + /// \brief String representation of the type of the value. + std::string getTypeAsString() const; + +private: + void reset(); + + /// \brief All supported value types. + enum ValueType { + VT_Nothing, + VT_Unsigned, + VT_String, + VT_Matcher + }; + + /// \brief All supported value types. + union AllValues { + unsigned Unsigned; + std::string *String; + VariantMatcher *Matcher; + }; + + ValueType Type; + AllValues Value; +}; + +} // end namespace dynamic +} // end namespace ast_matchers +} // end namespace clang + +#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/Consumed.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/Consumed.h new file mode 100644 index 0000000..23a094a --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/Consumed.h @@ -0,0 +1,264 @@ +//===- Consumed.h ----------------------------------------------*- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// A intra-procedural analysis for checking consumed properties. This is based, +// in part, on research on linear types. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CONSUMED_H +#define LLVM_CLANG_CONSUMED_H + +#include "clang/AST/DeclCXX.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/StmtCXX.h" +#include "clang/Analysis/AnalysisContext.h" +#include "clang/Analysis/Analyses/PostOrderCFGView.h" +#include "clang/Basic/SourceLocation.h" + +namespace clang { +namespace consumed { + + enum ConsumedState { + // No state information for the given variable. + CS_None, + + CS_Unknown, + CS_Unconsumed, + CS_Consumed + }; + + class ConsumedStmtVisitor; + + typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes; + typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag; + typedef std::list<DelayedDiag> DiagList; + + class ConsumedWarningsHandlerBase { + + public: + + virtual ~ConsumedWarningsHandlerBase(); + + /// \brief Emit the warnings and notes left by the analysis. + virtual void emitDiagnostics() {} + + /// \brief Warn that a variable's state doesn't match at the entry and exit + /// of a loop. + /// + /// \param Loc -- The location of the end of the loop. + /// + /// \param VariableName -- The name of the variable that has a mismatched + /// state. + virtual void warnLoopStateMismatch(SourceLocation Loc, + StringRef VariableName) {} + + /// \brief Warn about parameter typestate mismatches upon return. + /// + /// \param Loc -- The SourceLocation of the return statement. + /// + /// \param ExpectedState -- The state the return value was expected to be + /// in. + /// + /// \param ObservedState -- The state the return value was observed to be + /// in. + virtual void warnParamReturnTypestateMismatch(SourceLocation Loc, + StringRef VariableName, + StringRef ExpectedState, + StringRef ObservedState) {}; + + // FIXME: Add documentation. + virtual void warnParamTypestateMismatch(SourceLocation LOC, + StringRef ExpectedState, + StringRef ObservedState) {} + + // FIXME: This can be removed when the attr propagation fix for templated + // classes lands. + /// \brief Warn about return typestates set for unconsumable types. + /// + /// \param Loc -- The location of the attributes. + /// + /// \param TypeName -- The name of the unconsumable type. + virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc, + StringRef TypeName) {} + + /// \brief Warn about return typestate mismatches. + /// + /// \param Loc -- The SourceLocation of the return statement. + /// + /// \param ExpectedState -- The state the return value was expected to be + /// in. + /// + /// \param ObservedState -- The state the return value was observed to be + /// in. + virtual void warnReturnTypestateMismatch(SourceLocation Loc, + StringRef ExpectedState, + StringRef ObservedState) {} + + /// \brief Warn about use-while-consumed errors. + /// \param MethodName -- The name of the method that was incorrectly + /// invoked. + /// + /// \param State -- The state the object was used in. + /// + /// \param Loc -- The SourceLocation of the method invocation. + virtual void warnUseOfTempInInvalidState(StringRef MethodName, + StringRef State, + SourceLocation Loc) {} + + /// \brief Warn about use-while-consumed errors. + /// \param MethodName -- The name of the method that was incorrectly + /// invoked. + /// + /// \param State -- The state the object was used in. + /// + /// \param VariableName -- The name of the variable that holds the unique + /// value. + /// + /// \param Loc -- The SourceLocation of the method invocation. + virtual void warnUseInInvalidState(StringRef MethodName, + StringRef VariableName, + StringRef State, + SourceLocation Loc) {} + }; + + class ConsumedStateMap { + + typedef llvm::DenseMap<const VarDecl *, ConsumedState> VarMapType; + typedef llvm::DenseMap<const CXXBindTemporaryExpr *, ConsumedState> + TmpMapType; + + protected: + + bool Reachable; + const Stmt *From; + VarMapType VarMap; + TmpMapType TmpMap; + + public: + ConsumedStateMap() : Reachable(true), From(NULL) {} + ConsumedStateMap(const ConsumedStateMap &Other) + : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap), + TmpMap() {} + + /// \brief Warn if any of the parameters being tracked are not in the state + /// they were declared to be in upon return from a function. + void checkParamsForReturnTypestate(SourceLocation BlameLoc, + ConsumedWarningsHandlerBase &WarningsHandler) const; + + /// \brief Clear the TmpMap. + void clearTemporaries(); + + /// \brief Get the consumed state of a given variable. + ConsumedState getState(const VarDecl *Var) const; + + /// \brief Get the consumed state of a given temporary value. + ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const; + + /// \brief Merge this state map with another map. + void intersect(const ConsumedStateMap *Other); + + void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack, + const ConsumedStateMap *LoopBackStates, + ConsumedWarningsHandlerBase &WarningsHandler); + + /// \brief Return true if this block is reachable. + bool isReachable() const { return Reachable; } + + /// \brief Mark the block as unreachable. + void markUnreachable(); + + /// \brief Set the source for a decision about the branching of states. + /// \param Source -- The statement that was the origin of a branching + /// decision. + void setSource(const Stmt *Source) { this->From = Source; } + + /// \brief Set the consumed state of a given variable. + void setState(const VarDecl *Var, ConsumedState State); + + /// \brief Set the consumed state of a given temporary value. + void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State); + + /// \brief Remove the variable from our state map. + void remove(const VarDecl *Var); + + /// \brief Tests to see if there is a mismatch in the states stored in two + /// maps. + /// + /// \param Other -- The second map to compare against. + bool operator!=(const ConsumedStateMap *Other) const; + }; + + class ConsumedBlockInfo { + std::vector<ConsumedStateMap*> StateMapsArray; + std::vector<unsigned int> VisitOrder; + + public: + ConsumedBlockInfo() { } + + ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph) + : StateMapsArray(NumBlocks, 0), VisitOrder(NumBlocks, 0) { + unsigned int VisitOrderCounter = 0; + for (PostOrderCFGView::iterator BI = SortedGraph->begin(), + BE = SortedGraph->end(); BI != BE; ++BI) { + VisitOrder[(*BI)->getBlockID()] = VisitOrderCounter++; + } + } + + bool allBackEdgesVisited(const CFGBlock *CurrBlock, + const CFGBlock *TargetBlock); + + void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, + bool &AlreadyOwned); + void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap); + + ConsumedStateMap* borrowInfo(const CFGBlock *Block); + + void discardInfo(const CFGBlock *Block); + + ConsumedStateMap* getInfo(const CFGBlock *Block); + + bool isBackEdge(const CFGBlock *From, const CFGBlock *To); + bool isBackEdgeTarget(const CFGBlock *Block); + }; + + /// A class that handles the analysis of uniqueness violations. + class ConsumedAnalyzer { + + ConsumedBlockInfo BlockInfo; + ConsumedStateMap *CurrStates; + + ConsumedState ExpectedReturnState; + + void determineExpectedReturnState(AnalysisDeclContext &AC, + const FunctionDecl *D); + bool hasConsumableAttributes(const CXXRecordDecl *RD); + bool splitState(const CFGBlock *CurrBlock, + const ConsumedStmtVisitor &Visitor); + + public: + + ConsumedWarningsHandlerBase &WarningsHandler; + + ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler) + : WarningsHandler(WarningsHandler) {} + + ConsumedState getExpectedReturnState() const { return ExpectedReturnState; } + + /// \brief Check a function's CFG for consumed violations. + /// + /// We traverse the blocks in the CFG, keeping track of the state of each + /// value who's type has uniquness annotations. If methods are invoked in + /// the wrong state a warning is issued. Each block in the CFG is traversed + /// exactly once. + void run(AnalysisDeclContext &AC); + }; +}} // end namespace clang::consumed + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h index 05f48c6..75d7963 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/FormatString.h @@ -49,7 +49,7 @@ public: const char *toString() const { return representation; } // Overloaded operators for bool like qualities - operator bool() const { return flag; } + LLVM_EXPLICIT operator bool() const { return flag; } OptionalFlag& operator=(const bool &rhs) { flag = rhs; return *this; // Return a reference to myself. @@ -73,6 +73,9 @@ public: AsIntMax, // 'j' AsSizeT, // 'z' AsPtrDiff, // 't' + AsInt32, // 'I32' (MSVCRT, like __int32) + AsInt3264, // 'I' (MSVCRT, like __int3264 from MIDL) + AsInt64, // 'I64' (MSVCRT, like __int64) AsLongDouble, // 'L' AsAllocate, // for '%as', GNU extension to C90 scanf AsMAllocate, // for '%ms', GNU extension to scanf @@ -95,6 +98,9 @@ public: case AsLongLong: case AsChar: return 2; + case AsInt32: + case AsInt64: + return 3; case None: return 0; } 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 8a888e6..5def3dd 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h @@ -11,8 +11,8 @@ // A intra-procedural analysis for thread safety (e.g. deadlocks and race // conditions), based off of an annotation system. // -// See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety for more -// information. +// See http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking +// for more information. // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h index e8810c3..188722d 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/UninitializedValues.h @@ -38,6 +38,12 @@ private: /// The expression which uses this variable. const Expr *User; + /// Is this use uninitialized whenever the function is called? + bool UninitAfterCall; + + /// Is this use uninitialized whenever the variable declaration is reached? + bool UninitAfterDecl; + /// Does this use always see an uninitialized value? bool AlwaysUninit; @@ -46,13 +52,17 @@ private: SmallVector<Branch, 2> UninitBranches; public: - UninitUse(const Expr *User, bool AlwaysUninit) : - User(User), AlwaysUninit(AlwaysUninit) {} + UninitUse(const Expr *User, bool AlwaysUninit) + : User(User), UninitAfterCall(false), UninitAfterDecl(false), + AlwaysUninit(AlwaysUninit) {} void addUninitBranch(Branch B) { UninitBranches.push_back(B); } + void setUninitAfterCall() { UninitAfterCall = true; } + void setUninitAfterDecl() { UninitAfterDecl = true; } + /// Get the expression containing the uninitialized use. const Expr *getUser() const { return User; } @@ -62,6 +72,12 @@ public: Maybe, /// The use is uninitialized whenever a certain branch is taken. Sometimes, + /// The use is uninitialized the first time it is reached after we reach + /// the variable's declaration. + AfterDecl, + /// The use is uninitialized the first time it is reached after the function + /// is called. + AfterCall, /// The use is always uninitialized. Always }; @@ -69,6 +85,8 @@ public: /// Get the kind of uninitialized use. Kind getKind() const { return AlwaysUninit ? Always : + UninitAfterCall ? AfterCall : + UninitAfterDecl ? AfterDecl : !branch_empty() ? Sometimes : Maybe; } diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h index 46d7d07..b6f183d 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h @@ -16,18 +16,14 @@ #define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H #include "clang/AST/Decl.h" -#include "clang/AST/Expr.h" #include "clang/Analysis/CFG.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Allocator.h" namespace clang { -class Decl; class Stmt; class CFGReverseBlockReachabilityAnalysis; class CFGStmtMap; @@ -35,7 +31,6 @@ class LiveVariables; class ManagedAnalysis; class ParentMap; class PseudoConstantAnalysis; -class ImplicitParamDecl; class LocationContextManager; class StackFrameContext; class BlockInvocationContext; @@ -256,6 +251,7 @@ public: virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; + void dumpStack(raw_ostream &OS, StringRef Indent = "") const; LLVM_ATTRIBUTE_USED void dumpStack() const; public: diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h index d4e1f5f..33c940e 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/AnalysisDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define ANALYSISSTART #include "clang/Basic/DiagnosticAnalysisKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h index ee0be73..14b7ab8 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h @@ -43,6 +43,8 @@ namespace clang { class PrinterHelper; class LangOptions; class ASTContext; + class CXXRecordDecl; + class CXXDeleteExpr; /// CFGElement - Represents a top-level expression in a basic block. class CFGElement { @@ -53,6 +55,7 @@ public: Initializer, // dtor kind AutomaticObjectDtor, + DeleteDtor, BaseDtor, MemberDtor, TemporaryDtor, @@ -185,6 +188,31 @@ private: } }; +/// CFGDeleteDtor - Represents C++ object destructor generated +/// from a call to delete. +class CFGDeleteDtor : public CFGImplicitDtor { +public: + CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE) + : CFGImplicitDtor(DeleteDtor, RD, DE) {} + + const CXXRecordDecl *getCXXRecordDecl() const { + return static_cast<CXXRecordDecl*>(Data1.getPointer()); + } + + // Get Delete expression which triggered the destructor call. + const CXXDeleteExpr *getDeleteExpr() const { + return static_cast<CXXDeleteExpr *>(Data2.getPointer()); + } + + +private: + friend class CFGElement; + CFGDeleteDtor() {} + static bool isKind(const CFGElement &elem) { + return elem.getKind() == DeleteDtor; + } +}; + /// CFGBaseDtor - Represents C++ object destructor implicitly generated for /// base object in destructor. class CFGBaseDtor : public CFGImplicitDtor { @@ -269,7 +297,7 @@ public: Stmt &operator*() { return *getStmt(); } const Stmt &operator*() const { return *getStmt(); } - operator bool() const { return getStmt(); } + LLVM_EXPLICIT operator bool() const { return getStmt(); } }; /// CFGBlock - Represents a single basic block in a source-level CFG. @@ -564,6 +592,10 @@ public: Elements.push_back(CFGAutomaticObjDtor(VD, S), C); } + void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) { + Elements.push_back(CFGDeleteDtor(RD, DE), C); + } + // Destructors must be inserted in reversed order. So insertion is in two // steps. First we prepare space for some number of elements, then we insert // the elements beginning at the last position in prepared space. @@ -745,6 +777,35 @@ public: TryDispatchBlocks.push_back(block); } + /// Records a synthetic DeclStmt and the DeclStmt it was constructed from. + /// + /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains + /// multiple decls. + void addSyntheticDeclStmt(const DeclStmt *Synthetic, + const DeclStmt *Source) { + assert(Synthetic->isSingleDecl() && "Can handle single declarations only"); + assert(Synthetic != Source && "Don't include original DeclStmts in map"); + assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map"); + SyntheticDeclStmts[Synthetic] = Source; + } + + typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator + synthetic_stmt_iterator; + + /// Iterates over synthetic DeclStmts in the CFG. + /// + /// Each element is a (synthetic statement, source statement) pair. + /// + /// \sa addSyntheticDeclStmt + synthetic_stmt_iterator synthetic_stmt_begin() const { + return SyntheticDeclStmts.begin(); + } + + /// \sa synthetic_stmt_begin + synthetic_stmt_iterator synthetic_stmt_end() const { + return SyntheticDeclStmts.end(); + } + //===--------------------------------------------------------------------===// // Member templates useful for various batch operations over CFGs. //===--------------------------------------------------------------------===// @@ -763,21 +824,6 @@ public: // CFG Introspection. //===--------------------------------------------------------------------===// - struct BlkExprNumTy { - const signed Idx; - explicit BlkExprNumTy(signed idx) : Idx(idx) {} - explicit BlkExprNumTy() : Idx(-1) {} - operator bool() const { return Idx >= 0; } - operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; } - }; - - bool isBlkExpr(const Stmt *S) { return getBlkExprNum(S); } - bool isBlkExpr(const Stmt *S) const { - return const_cast<CFG*>(this)->isBlkExpr(S); - } - BlkExprNumTy getBlkExprNum(const Stmt *S); - unsigned getNumBlkExprs(); - /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which /// start at 0). unsigned getNumBlockIDs() const { return NumBlockIDs; } @@ -800,9 +846,7 @@ public: //===--------------------------------------------------------------------===// CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0), - BlkExprMap(NULL), Blocks(BlkBVC, 10) {} - - ~CFG(); + Blocks(BlkBVC, 10) {} llvm::BumpPtrAllocator& getAllocator() { return BlkBVC.getAllocator(); @@ -819,11 +863,6 @@ private: // for indirect gotos unsigned NumBlockIDs; - // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h. - // It represents a map from Expr* to integers to record the set of - // block-level expressions and their "statement number" in the CFG. - void * BlkExprMap; - BumpVectorContext BlkBVC; CFGBlockListTy Blocks; @@ -832,6 +871,9 @@ private: /// This is the collection of such blocks present in the CFG. std::vector<const CFGBlock *> TryDispatchBlocks; + /// Collects DeclStmts synthesized for this CFG and maps each one back to its + /// source DeclStmt. + llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts; }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/CallGraph.h b/contrib/llvm/tools/clang/include/clang/Analysis/CallGraph.h index 5015eb6..593ba57 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/CallGraph.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/CallGraph.h @@ -144,8 +144,8 @@ private: public: CallGraphNode(Decl *D) : FD(D) {} - typedef SmallVector<CallRecord, 5>::iterator iterator; - typedef SmallVector<CallRecord, 5>::const_iterator const_iterator; + typedef SmallVectorImpl<CallRecord>::iterator iterator; + typedef SmallVectorImpl<CallRecord>::const_iterator const_iterator; /// Iterators through all the callees/children of the node. inline iterator begin() { return CalledFunctions.begin(); } diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h index 0f5e7bf..c611ea2 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h @@ -45,8 +45,7 @@ public: /// dequeue - Remove a block from the worklist. const CFGBlock *dequeue() { assert(!BlockQueue.empty()); - const CFGBlock *B = BlockQueue.back(); - BlockQueue.pop_back(); + const CFGBlock *B = BlockQueue.pop_back_val(); BlockSet[B] = 0; return B; } diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h b/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h deleted file mode 100644 index 35cc799..0000000 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h +++ /dev/null @@ -1,307 +0,0 @@ -// BlkExprDeclBitVector.h - Dataflow types for Bitvector Analysis --*- C++ --*-- -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides definition of dataflow types used by analyses such -// as LiveVariables and UninitializedValues. The underlying dataflow values -// are implemented as bitvectors, but the definitions in this file include -// the necessary boilerplate to use with our dataflow framework. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STMTDECLBVDVAL_H -#define LLVM_CLANG_STMTDECLBVDVAL_H - -#include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion -#include "clang/Analysis/CFG.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/DenseMap.h" - -namespace clang { - - class Stmt; - class ASTContext; - -struct DeclBitVector_Types { - - class Idx { - unsigned I; - public: - explicit Idx(unsigned i) : I(i) {} - Idx() : I(~0U) {} - - bool isValid() const { - return I != ~0U; - } - operator unsigned() const { - assert (isValid()); - return I; - } - }; - - //===--------------------------------------------------------------------===// - // AnalysisDataTy - Whole-function meta data. - //===--------------------------------------------------------------------===// - - class AnalysisDataTy { - public: - typedef llvm::DenseMap<const NamedDecl*, unsigned > DMapTy; - typedef DMapTy::const_iterator decl_iterator; - - protected: - DMapTy DMap; - unsigned NDecls; - - public: - - AnalysisDataTy() : NDecls(0) {} - virtual ~AnalysisDataTy() {} - - bool isTracked(const NamedDecl *SD) { return DMap.find(SD) != DMap.end(); } - - Idx getIdx(const NamedDecl *SD) const { - DMapTy::const_iterator I = DMap.find(SD); - return I == DMap.end() ? Idx() : Idx(I->second); - } - - unsigned getNumDecls() const { return NDecls; } - - void Register(const NamedDecl *SD) { - if (!isTracked(SD)) DMap[SD] = NDecls++; - } - - decl_iterator begin_decl() const { return DMap.begin(); } - decl_iterator end_decl() const { return DMap.end(); } - }; - - //===--------------------------------------------------------------------===// - // ValTy - Dataflow value. - //===--------------------------------------------------------------------===// - - class ValTy { - llvm::BitVector DeclBV; - public: - - void resetDeclValues(AnalysisDataTy& AD) { - DeclBV.resize(AD.getNumDecls()); - DeclBV.reset(); - } - - void setDeclValues(AnalysisDataTy& AD) { - DeclBV.resize(AD.getNumDecls()); - DeclBV.set(); - } - - void resetValues(AnalysisDataTy& AD) { - resetDeclValues(AD); - } - - bool operator==(const ValTy& RHS) const { - assert (sizesEqual(RHS)); - return DeclBV == RHS.DeclBV; - } - - void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; } - - llvm::BitVector::reference getBit(unsigned i) { - return DeclBV[i]; - } - - bool getBit(unsigned i) const { - return DeclBV[i]; - } - - llvm::BitVector::reference - operator()(const NamedDecl *ND, const AnalysisDataTy& AD) { - return getBit(AD.getIdx(ND)); - } - - bool operator()(const NamedDecl *ND, const AnalysisDataTy& AD) const { - return getBit(AD.getIdx(ND)); - } - - llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; } - const llvm::BitVector::reference getDeclBit(unsigned i) const { - return const_cast<llvm::BitVector&>(DeclBV)[i]; - } - - ValTy& operator|=(const ValTy& RHS) { - assert (sizesEqual(RHS)); - DeclBV |= RHS.DeclBV; - return *this; - } - - ValTy& operator&=(const ValTy& RHS) { - assert (sizesEqual(RHS)); - DeclBV &= RHS.DeclBV; - return *this; - } - - ValTy& OrDeclBits(const ValTy& RHS) { - return operator|=(RHS); - } - - ValTy& AndDeclBits(const ValTy& RHS) { - return operator&=(RHS); - } - - bool sizesEqual(const ValTy& RHS) const { - return DeclBV.size() == RHS.DeclBV.size(); - } - }; - - //===--------------------------------------------------------------------===// - // Some useful merge operations. - //===--------------------------------------------------------------------===// - - struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } }; - struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } }; -}; - - -struct StmtDeclBitVector_Types { - - //===--------------------------------------------------------------------===// - // AnalysisDataTy - Whole-function meta data. - //===--------------------------------------------------------------------===// - - class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy { - ASTContext *ctx; - CFG* cfg; - public: - AnalysisDataTy() : ctx(0), cfg(0) {} - virtual ~AnalysisDataTy() {} - - void setContext(ASTContext &c) { ctx = &c; } - ASTContext &getContext() { - assert(ctx && "ASTContext should not be NULL."); - return *ctx; - } - - void setCFG(CFG& c) { cfg = &c; } - CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; } - - bool isTracked(const Stmt *S) { return cfg->isBlkExpr(S); } - using DeclBitVector_Types::AnalysisDataTy::isTracked; - - unsigned getIdx(const Stmt *S) const { - CFG::BlkExprNumTy I = cfg->getBlkExprNum(S); - assert(I && "Stmtession not tracked for bitvector."); - return I; - } - using DeclBitVector_Types::AnalysisDataTy::getIdx; - - unsigned getNumBlkExprs() const { return cfg->getNumBlkExprs(); } - }; - - //===--------------------------------------------------------------------===// - // ValTy - Dataflow value. - //===--------------------------------------------------------------------===// - - class ValTy : public DeclBitVector_Types::ValTy { - llvm::BitVector BlkExprBV; - typedef DeclBitVector_Types::ValTy ParentTy; - - static inline ParentTy& ParentRef(ValTy& X) { - return static_cast<ParentTy&>(X); - } - - static inline const ParentTy& ParentRef(const ValTy& X) { - return static_cast<const ParentTy&>(X); - } - - public: - - void resetBlkExprValues(AnalysisDataTy& AD) { - BlkExprBV.resize(AD.getNumBlkExprs()); - BlkExprBV.reset(); - } - - void setBlkExprValues(AnalysisDataTy& AD) { - BlkExprBV.resize(AD.getNumBlkExprs()); - BlkExprBV.set(); - } - - void resetValues(AnalysisDataTy& AD) { - resetDeclValues(AD); - resetBlkExprValues(AD); - } - - void setValues(AnalysisDataTy& AD) { - setDeclValues(AD); - setBlkExprValues(AD); - } - - bool operator==(const ValTy& RHS) const { - return ParentRef(*this) == ParentRef(RHS) - && BlkExprBV == RHS.BlkExprBV; - } - - void copyValues(const ValTy& RHS) { - ParentRef(*this).copyValues(ParentRef(RHS)); - BlkExprBV = RHS.BlkExprBV; - } - - llvm::BitVector::reference - operator()(const Stmt *S, const AnalysisDataTy& AD) { - return BlkExprBV[AD.getIdx(S)]; - } - const llvm::BitVector::reference - operator()(const Stmt *S, const AnalysisDataTy& AD) const { - return const_cast<ValTy&>(*this)(S,AD); - } - - using DeclBitVector_Types::ValTy::operator(); - - - llvm::BitVector::reference getStmtBit(unsigned i) { return BlkExprBV[i]; } - const llvm::BitVector::reference getStmtBit(unsigned i) const { - return const_cast<llvm::BitVector&>(BlkExprBV)[i]; - } - - ValTy& OrBlkExprBits(const ValTy& RHS) { - BlkExprBV |= RHS.BlkExprBV; - return *this; - } - - ValTy& AndBlkExprBits(const ValTy& RHS) { - BlkExprBV &= RHS.BlkExprBV; - return *this; - } - - ValTy& operator|=(const ValTy& RHS) { - assert (sizesEqual(RHS)); - ParentRef(*this) |= ParentRef(RHS); - BlkExprBV |= RHS.BlkExprBV; - return *this; - } - - ValTy& operator&=(const ValTy& RHS) { - assert (sizesEqual(RHS)); - ParentRef(*this) &= ParentRef(RHS); - BlkExprBV &= RHS.BlkExprBV; - return *this; - } - - bool sizesEqual(const ValTy& RHS) const { - return ParentRef(*this).sizesEqual(ParentRef(RHS)) - && BlkExprBV.size() == RHS.BlkExprBV.size(); - } - }; - - //===--------------------------------------------------------------------===// - // Some useful merge operations. - //===--------------------------------------------------------------------===// - - struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } }; - struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } }; - -}; -} // end namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h deleted file mode 100644 index 2bf3eda..0000000 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h +++ /dev/null @@ -1,107 +0,0 @@ -//= CFGRecStmtDeclVisitor - Recursive visitor of CFG stmts/decls -*- 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 template class CFGRecStmtDeclVisitor, which extends -// CFGRecStmtVisitor by implementing (typed) visitation of decls. -// -// FIXME: This may not be fully complete. We currently explore only subtypes -// of ScopedDecl. -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H -#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H - -#include "clang/AST/Decl.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclObjC.h" -#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h" - -#define DISPATCH_CASE(CLASS) \ -case Decl::CLASS: \ -static_cast<ImplClass*>(this)->Visit##CLASS##Decl( \ - static_cast<CLASS##Decl*>(D)); \ -break; - -#define DEFAULT_DISPATCH(CLASS) void Visit##CLASS##Decl(CLASS##Decl *D) {} -#define DEFAULT_DISPATCH_VARDECL(CLASS) void Visit##CLASS##Decl(CLASS##Decl *D)\ - { static_cast<ImplClass*>(this)->VisitVarDecl(D); } - - -namespace clang { -template <typename ImplClass> -class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor<ImplClass> { -public: - - void VisitDeclRefExpr(DeclRefExpr *DR) { - static_cast<ImplClass*>(this)->VisitDecl(DR->getDecl()); - } - - void VisitDeclStmt(DeclStmt *DS) { - for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end(); - DI != DE; ++DI) { - Decl *D = *DI; - static_cast<ImplClass*>(this)->VisitDecl(D); - // Visit the initializer. - if (VarDecl *VD = dyn_cast<VarDecl>(D)) - if (Expr *I = VD->getInit()) - static_cast<ImplClass*>(this)->Visit(I); - } - } - - void VisitDecl(Decl *D) { - switch (D->getKind()) { - DISPATCH_CASE(Function) - DISPATCH_CASE(CXXMethod) - DISPATCH_CASE(Var) - DISPATCH_CASE(ParmVar) // FIXME: (same) - DISPATCH_CASE(ImplicitParam) - DISPATCH_CASE(EnumConstant) - DISPATCH_CASE(Typedef) - DISPATCH_CASE(TypeAlias) - DISPATCH_CASE(Record) // FIXME: Refine. VisitStructDecl? - DISPATCH_CASE(CXXRecord) - DISPATCH_CASE(Enum) - DISPATCH_CASE(Field) - DISPATCH_CASE(UsingDirective) - DISPATCH_CASE(Using) - DISPATCH_CASE(NamespaceAlias) - default: - llvm_unreachable("Subtype of ScopedDecl not handled."); - } - } - - DEFAULT_DISPATCH(Var) - DEFAULT_DISPATCH(Function) - DEFAULT_DISPATCH(CXXMethod) - DEFAULT_DISPATCH_VARDECL(ParmVar) - DEFAULT_DISPATCH(ImplicitParam) - DEFAULT_DISPATCH(EnumConstant) - DEFAULT_DISPATCH(Typedef) - DEFAULT_DISPATCH(TypeAlias) - DEFAULT_DISPATCH(Record) - DEFAULT_DISPATCH(Enum) - DEFAULT_DISPATCH(Field) - DEFAULT_DISPATCH(ObjCInterface) - DEFAULT_DISPATCH(ObjCMethod) - DEFAULT_DISPATCH(ObjCProtocol) - DEFAULT_DISPATCH(ObjCCategory) - DEFAULT_DISPATCH(UsingDirective) - DEFAULT_DISPATCH(Using) - DEFAULT_DISPATCH(NamespaceAlias) - - void VisitCXXRecordDecl(CXXRecordDecl *D) { - static_cast<ImplClass*>(this)->VisitRecordDecl(D); - } -}; - -} // end namespace clang - -#undef DISPATCH_CASE -#undef DEFAULT_DISPATCH -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h deleted file mode 100644 index 4d1cabf..0000000 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGRecStmtVisitor.h +++ /dev/null @@ -1,59 +0,0 @@ -//==- CFGRecStmtVisitor - Recursive visitor of CFG statements ---*- 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 template class CFGRecStmtVisitor, which extends -// CFGStmtVisitor by implementing a default recursive visit of all statements. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H -#define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_VISITOR_H - -#include "clang/Analysis/Visitors/CFGStmtVisitor.h" - -namespace clang { -template <typename ImplClass> -class CFGRecStmtVisitor : public CFGStmtVisitor<ImplClass,void> { -public: - - void VisitStmt(Stmt *S) { - static_cast< ImplClass* >(this)->VisitChildren(S); - } - - void VisitCompoundStmt(CompoundStmt *S) { - // Do nothing. Everything in a CompoundStmt is inlined - // into the CFG. - } - - void VisitConditionVariableInit(Stmt *S) { - assert(S == this->getCurrentBlkStmt()); - VarDecl *CondVar = 0; - switch (S->getStmtClass()) { -#define CONDVAR_CASE(CLASS) \ -case Stmt::CLASS ## Class:\ -CondVar = cast<CLASS>(S)->getConditionVariable();\ -break; - CONDVAR_CASE(IfStmt) - CONDVAR_CASE(ForStmt) - CONDVAR_CASE(SwitchStmt) - CONDVAR_CASE(WhileStmt) -#undef CONDVAR_CASE - default: - llvm_unreachable("Infeasible"); - } - static_cast<ImplClass*>(this)->Visit(CondVar->getInit()); - } - - // Defining operator() allows the visitor to be used as a C++ style functor. - void operator()(Stmt *S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);} -}; - -} // end namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h b/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h deleted file mode 100644 index b354ba7..0000000 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Visitors/CFGStmtVisitor.h +++ /dev/null @@ -1,175 +0,0 @@ -//===--- CFGStmtVisitor.h - Visitor for Stmts in a CFG ----------*- 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 CFGStmtVisitor interface, which extends -// StmtVisitor. This interface is useful for visiting statements in a CFG -// where some statements have implicit control-flow and thus should -// be treated specially. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H -#define LLVM_CLANG_ANALYSIS_CFGSTMTVISITOR_H - -#include "clang/AST/StmtVisitor.h" -#include "clang/Analysis/CFG.h" - -namespace clang { - -#define DISPATCH_CASE(CLASS) \ -case Stmt::CLASS ## Class: return \ -static_cast<ImplClass*>(this)->BlockStmt_Visit ## CLASS(static_cast<CLASS*>(S)); - -#define DEFAULT_BLOCKSTMT_VISIT(CLASS) RetTy BlockStmt_Visit ## CLASS(CLASS *S)\ -{ return\ - static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(\ - cast<Expr>(S)); } - -template <typename ImplClass, typename RetTy=void> -class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> { - Stmt *CurrentBlkStmt; - - struct NullifyStmt { - Stmt*& S; - - NullifyStmt(Stmt*& s) : S(s) {} - ~NullifyStmt() { S = NULL; } - }; - -public: - CFGStmtVisitor() : CurrentBlkStmt(NULL) {} - - Stmt *getCurrentBlkStmt() const { return CurrentBlkStmt; } - - RetTy Visit(Stmt *S) { - if (S == CurrentBlkStmt || - !static_cast<ImplClass*>(this)->getCFG().isBlkExpr(S)) - return StmtVisitor<ImplClass,RetTy>::Visit(S); - else - return RetTy(); - } - - /// VisitConditionVariableInit - Handle the initialization of condition - /// variables at branches. Valid statements include IfStmt, ForStmt, - /// WhileStmt, and SwitchStmt. - RetTy VisitConditionVariableInit(Stmt *S) { - return RetTy(); - } - - /// BlockVisit_XXX - Visitor methods for visiting the "root" statements in - /// CFGBlocks. Root statements are the statements that appear explicitly in - /// the list of statements in a CFGBlock. For substatements, or when there - /// is no implementation provided for a BlockStmt_XXX method, we default - /// to using StmtVisitor's Visit method. - RetTy BlockStmt_Visit(Stmt *S) { - CurrentBlkStmt = S; - NullifyStmt cleanup(CurrentBlkStmt); - - switch (S->getStmtClass()) { - case Stmt::IfStmtClass: - case Stmt::ForStmtClass: - case Stmt::WhileStmtClass: - case Stmt::SwitchStmtClass: - return static_cast<ImplClass*>(this)->VisitConditionVariableInit(S); - - DISPATCH_CASE(StmtExpr) - DISPATCH_CASE(ConditionalOperator) - DISPATCH_CASE(BinaryConditionalOperator) - DISPATCH_CASE(ObjCForCollectionStmt) - DISPATCH_CASE(CXXForRangeStmt) - - case Stmt::BinaryOperatorClass: { - BinaryOperator* B = cast<BinaryOperator>(S); - if (B->isLogicalOp()) - return static_cast<ImplClass*>(this)->BlockStmt_VisitLogicalOp(B); - else if (B->getOpcode() == BO_Comma) - return static_cast<ImplClass*>(this)->BlockStmt_VisitComma(B); - // Fall through. - } - - default: - if (isa<Expr>(S)) - return - static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(cast<Expr>(S)); - else - return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); - } - } - - DEFAULT_BLOCKSTMT_VISIT(StmtExpr) - DEFAULT_BLOCKSTMT_VISIT(ConditionalOperator) - DEFAULT_BLOCKSTMT_VISIT(BinaryConditionalOperator) - - RetTy BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { - return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); - } - - RetTy BlockStmt_VisitCXXForRangeStmt(CXXForRangeStmt *S) { - return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S); - } - - RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr *E) { - return static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(E); - } - - RetTy BlockStmt_VisitExpr(Expr *E) { - return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(E); - } - - RetTy BlockStmt_VisitStmt(Stmt *S) { - return static_cast<ImplClass*>(this)->Visit(S); - } - - RetTy BlockStmt_VisitLogicalOp(BinaryOperator* B) { - return - static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B); - } - - RetTy BlockStmt_VisitComma(BinaryOperator* B) { - return - static_cast<ImplClass*>(this)->BlockStmt_VisitImplicitControlFlowExpr(B); - } - - //===--------------------------------------------------------------------===// - // Utility methods. Not called by default (but subclasses may use them). - //===--------------------------------------------------------------------===// - - /// VisitChildren: Call "Visit" on each child of S. - void VisitChildren(Stmt *S) { - - switch (S->getStmtClass()) { - default: - break; - - case Stmt::StmtExprClass: { - CompoundStmt *CS = cast<StmtExpr>(S)->getSubStmt(); - if (CS->body_empty()) return; - static_cast<ImplClass*>(this)->Visit(CS->body_back()); - return; - } - - case Stmt::BinaryOperatorClass: { - BinaryOperator* B = cast<BinaryOperator>(S); - if (B->getOpcode() != BO_Comma) break; - static_cast<ImplClass*>(this)->Visit(B->getRHS()); - return; - } - } - - for (Stmt::child_range I = S->children(); I; ++I) - if (*I) static_cast<ImplClass*>(this)->Visit(*I); - } -}; - -#undef DEFAULT_BLOCKSTMT_VISIT -#undef DISPATCH_CASE - -} // end namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/ABI.h b/contrib/llvm/tools/clang/include/clang/Basic/ABI.h index fecf613..3b3d59e 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/ABI.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/ABI.h @@ -39,28 +39,64 @@ struct ReturnAdjustment { /// \brief The non-virtual adjustment from the derived object to its /// nearest virtual base. int64_t NonVirtual; + + /// \brief Holds the ABI-specific information about the virtual return + /// adjustment, if needed. + union VirtualAdjustment { + // Itanium ABI + struct { + /// \brief The offset (in bytes), relative to the address point + /// of the virtual base class offset. + int64_t VBaseOffsetOffset; + } Itanium; + + // Microsoft ABI + struct { + /// \brief The offset (in bytes) of the vbptr, relative to the beginning + /// of the derived class. + uint32_t VBPtrOffset; + + /// \brief Index of the virtual base in the vbtable. + uint32_t VBIndex; + } Microsoft; + + VirtualAdjustment() { + memset(this, 0, sizeof(*this)); + } + + bool Equals(const VirtualAdjustment &Other) const { + return memcmp(this, &Other, sizeof(Other)) == 0; + } + + bool isEmpty() const { + VirtualAdjustment Zero; + return Equals(Zero); + } + + bool Less(const VirtualAdjustment &RHS) const { + return memcmp(this, &RHS, sizeof(RHS)) < 0; + } + } Virtual; - /// \brief The offset (in bytes), relative to the address point - /// of the virtual base class offset. - int64_t VBaseOffsetOffset; - - ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { } + ReturnAdjustment() : NonVirtual(0) {} - bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; } + bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); } friend bool operator==(const ReturnAdjustment &LHS, const ReturnAdjustment &RHS) { - return LHS.NonVirtual == RHS.NonVirtual && - LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset; + return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual); + } + + friend bool operator!=(const ReturnAdjustment &LHS, const ReturnAdjustment &RHS) { + return !(LHS == RHS); } friend bool operator<(const ReturnAdjustment &LHS, const ReturnAdjustment &RHS) { if (LHS.NonVirtual < RHS.NonVirtual) return true; - - return LHS.NonVirtual == RHS.NonVirtual && - LHS.VBaseOffsetOffset < RHS.VBaseOffsetOffset; + + return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual); } }; @@ -70,18 +106,57 @@ struct ThisAdjustment { /// nearest virtual base. int64_t NonVirtual; - /// \brief The offset (in bytes), relative to the address point, - /// of the virtual call offset. - int64_t VCallOffsetOffset; + /// \brief Holds the ABI-specific information about the virtual this + /// adjustment, if needed. + union VirtualAdjustment { + // Itanium ABI + struct { + /// \brief The offset (in bytes), relative to the address point, + /// of the virtual call offset. + int64_t VCallOffsetOffset; + } Itanium; + + struct { + /// \brief The offset of the vtordisp (in bytes), relative to the ECX. + int32_t VtordispOffset; + + /// \brief The offset of the vbptr of the derived class (in bytes), + /// relative to the ECX after vtordisp adjustment. + int32_t VBPtrOffset; + + /// \brief The offset (in bytes) of the vbase offset in the vbtable. + int32_t VBOffsetOffset; + } Microsoft; + + VirtualAdjustment() { + memset(this, 0, sizeof(*this)); + } + + bool Equals(const VirtualAdjustment &Other) const { + return memcmp(this, &Other, sizeof(Other)) == 0; + } + + bool isEmpty() const { + VirtualAdjustment Zero; + return Equals(Zero); + } + + bool Less(const VirtualAdjustment &RHS) const { + return memcmp(this, &RHS, sizeof(RHS)) < 0; + } + } Virtual; - ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { } + ThisAdjustment() : NonVirtual(0) { } - bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; } + bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); } friend bool operator==(const ThisAdjustment &LHS, const ThisAdjustment &RHS) { - return LHS.NonVirtual == RHS.NonVirtual && - LHS.VCallOffsetOffset == RHS.VCallOffsetOffset; + return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual); + } + + friend bool operator!=(const ThisAdjustment &LHS, const ThisAdjustment &RHS) { + return !(LHS == RHS); } friend bool operator<(const ThisAdjustment &LHS, @@ -89,11 +164,12 @@ struct ThisAdjustment { if (LHS.NonVirtual < RHS.NonVirtual) return true; - return LHS.NonVirtual == RHS.NonVirtual && - LHS.VCallOffsetOffset < RHS.VCallOffsetOffset; + return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual); } }; +class CXXMethodDecl; + /// \brief The \c this pointer adjustment as well as an optional return /// adjustment for a thunk. struct ThunkInfo { @@ -103,23 +179,25 @@ struct ThunkInfo { /// \brief The return adjustment. ReturnAdjustment Return; - ThunkInfo() { } + /// \brief Holds a pointer to the overridden method this thunk is for, + /// if needed by the ABI to distinguish different thunks with equal + /// adjustments. Otherwise, null. + /// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using + /// an ABI-specific comparator. + const CXXMethodDecl *Method; - ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return) - : This(This), Return(Return) { } + ThunkInfo() : Method(0) { } - friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) { - return LHS.This == RHS.This && LHS.Return == RHS.Return; - } + ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return, + const CXXMethodDecl *Method = 0) + : This(This), Return(Return), Method(Method) {} - friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) { - if (LHS.This < RHS.This) - return true; - - return LHS.This == RHS.This && LHS.Return < RHS.Return; + friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) { + return LHS.This == RHS.This && LHS.Return == RHS.Return && + LHS.Method == RHS.Method; } - bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); } + bool isEmpty() const { return This.isEmpty() && Return.isEmpty() && Method == 0; } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td index f769608..8c3bdba 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td @@ -1,8 +1,11 @@ -//////////////////////////////////////////////////////////////////////////////// -// Note: This file is a work in progress. Please do not apply non-trivial -// updates unless you have talked to Sean Hunt <rideau3@gmail.com> prior. -// Merely adding a new attribute is a trivial update. -//////////////////////////////////////////////////////////////////////////////// +//==--- Attr.td - attribute definitions -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // An attribute's subject is whatever it appertains to. In this file, it is // more accurately a list of things that an attribute can appertain to. All @@ -36,45 +39,53 @@ def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable", S->getKind() != Decl::ImplicitParam && S->getKind() != Decl::ParmVar && S->getKind() != Decl::NonTypeTemplateParm}]>; -def CXXVirtualMethod : SubsetSubject<CXXRecord, "virtual member function", - [{S->isVirtual()}]>; def NonBitField : SubsetSubject<Field, "non-bit field", [{!S->isBitField()}]>; // A single argument to an attribute -class Argument<string name> { +class Argument<string name, bit optional> { string Name = name; + bit Optional = optional; } -class BoolArgument<string name> : Argument<name>; -class IdentifierArgument<string name> : Argument<name>; -class IntArgument<string name> : Argument<name>; -class StringArgument<string name> : Argument<name>; -class ExprArgument<string name> : Argument<name>; -class FunctionArgument<string name> : Argument<name>; -class TypeArgument<string name> : Argument<name>; -class UnsignedArgument<string name> : Argument<name>; -class SourceLocArgument<string name> : Argument<name>; -class VariadicUnsignedArgument<string name> : Argument<name>; -class VariadicExprArgument<string name> : Argument<name>; +class BoolArgument<string name, bit opt = 0> : Argument<name, opt>; +class IdentifierArgument<string name, bit opt = 0> : Argument<name, opt>; +class IntArgument<string name, bit opt = 0> : Argument<name, opt>; +class StringArgument<string name, bit opt = 0> : Argument<name, opt>; +class ExprArgument<string name, bit opt = 0> : Argument<name, opt>; +class FunctionArgument<string name, bit opt = 0> : Argument<name, opt>; +class TypeArgument<string name, bit opt = 0> : Argument<name, opt>; +class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>; +class SourceLocArgument<string name, bit opt = 0> : Argument<name, opt>; +class VariadicUnsignedArgument<string name> : Argument<name, 1>; +class VariadicExprArgument<string name> : Argument<name, 1>; // A version of the form major.minor[.subminor]. -class VersionArgument<string name> : Argument<name>; +class VersionArgument<string name, bit opt = 0> : Argument<name, opt>; // This one's a doozy, so it gets its own special type // It can be an unsigned integer, or a type. Either can // be dependent. -class AlignedArgument<string name> : Argument<name>; +class AlignedArgument<string name, bit opt = 0> : Argument<name, opt>; // An integer argument with a default value -class DefaultIntArgument<string name, int default> : IntArgument<name> { +class DefaultIntArgument<string name, int default> : IntArgument<name, 1> { int Default = default; } // This argument is more complex, it includes the enumerator type name, // a list of strings to accept, and a list of enumerators to map them to. class EnumArgument<string name, string type, list<string> values, - list<string> enums> : Argument<name> { + list<string> enums, bit opt = 0> : Argument<name, opt> { + string Type = type; + list<string> Values = values; + list<string> Enums = enums; +} + +// FIXME: There should be a VariadicArgument type that takes any other type +// of argument and generates the appropriate type. +class VariadicEnumArgument<string name, string type, list<string> values, + list<string> enums> : Argument<name, 1> { string Type = type; list<string> Values = values; list<string> Enums = enums; @@ -122,13 +133,27 @@ class Attr { bit Ignored = 0; // Set to true if each of the spellings is a distinct attribute. bit DistinctSpellings = 0; + // Set to true if the attribute's parsing does not match its semantic + // content. Eg) It parses 3 args, but semantically takes 4 args. Opts out of + // common attribute error checking. + bit HasCustomParsing = 0; // Any additional text that should be included verbatim in the class. code AdditionalMembers = [{}]; } +/// A type attribute is not processed on a declaration or a statement. +class TypeAttr : Attr { + let ASTNode = 0; +} + /// An inheritable attribute is inherited by later redeclarations. class InheritableAttr : Attr; +/// A target-specific attribute that is meant to be processed via +/// TargetAttributesSema::ProcessDeclAttribute. This class is meant to be used +/// as a mixin with InheritableAttr or Attr depending on the attribute's needs. +class TargetSpecificAttr; + /// An inheritable parameter attribute is inherited by later /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; @@ -144,13 +169,12 @@ class IgnoredAttr : Attr { // Attributes begin here // -def AddressSpace : Attr { +def AddressSpace : TypeAttr { let Spellings = [GNU<"address_space">]; let Args = [IntArgument<"AddressSpace">]; - let ASTNode = 0; } -def Alias : InheritableAttr { +def Alias : Attr { let Spellings = [GNU<"alias">, CXX11<"gnu", "alias">]; let Args = [StringArgument<"Aliasee">]; } @@ -159,7 +183,7 @@ def Aligned : InheritableAttr { let Spellings = [GNU<"aligned">, Declspec<"align">, CXX11<"gnu", "aligned">, Keyword<"alignas">, Keyword<"_Alignas">]; let Subjects = [NonBitField, NormalVar, Tag]; - let Args = [AlignedArgument<"Alignment">]; + let Args = [AlignedArgument<"Alignment", 1>]; let Accessors = [Accessor<"isGNU", [GNU<"aligned">, CXX11<"gnu","aligned">]>, Accessor<"isC11", [Keyword<"_Alignas">]>, Accessor<"isAlignas", [Keyword<"alignas">, @@ -172,7 +196,7 @@ def AlignMac68k : InheritableAttr { let SemaHandler = 0; } -def AllocSize : Attr { +def AllocSize : InheritableAttr { let Spellings = [GNU<"alloc_size">, CXX11<"gnu", "alloc_size">]; let Args = [VariadicUnsignedArgument<"Args">]; } @@ -196,6 +220,14 @@ def Annotate : InheritableParamAttr { let Args = [StringArgument<"Annotation">]; } +def ARMInterrupt : InheritableAttr, TargetSpecificAttr { + let Spellings = [GNU<"interrupt">]; + let Args = [EnumArgument<"Interrupt", "InterruptType", + ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], + ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"], + 1>]; +} + def AsmLabel : InheritableAttr { let Spellings = []; let Args = [StringArgument<"Label">]; @@ -214,6 +246,7 @@ def Availability : InheritableAttr { .Case("macosx", "OS X") .Default(llvm::StringRef()); } }]; + let HasCustomParsing = 1; } def Blocks : InheritableAttr { @@ -282,12 +315,13 @@ def Common : InheritableAttr { } def Const : InheritableAttr { - let Spellings = [GNU<"const">, GNU<"__const">, CXX11<"gnu", "const">]; + let Spellings = [GNU<"const">, GNU<"__const">, + CXX11<"gnu", "const">, CXX11<"gnu", "__const">]; } def Constructor : InheritableAttr { let Spellings = [GNU<"constructor">, CXX11<"gnu", "constructor">]; - let Args = [IntArgument<"Priority">]; + let Args = [IntArgument<"Priority", 1>]; } def CUDAConstant : InheritableAttr { @@ -326,7 +360,7 @@ def CXX11NoReturn : InheritableAttr { let Subjects = [Function]; } -def OpenCLKernel : Attr { +def OpenCLKernel : InheritableAttr { let Spellings = [Keyword<"__kernel">, Keyword<"kernel">]; } @@ -336,13 +370,14 @@ def OpenCLImageAccess : Attr { } def Deprecated : InheritableAttr { - let Spellings = [GNU<"deprecated">, CXX11<"gnu", "deprecated">]; - let Args = [StringArgument<"Message">]; + let Spellings = [GNU<"deprecated">, + CXX11<"gnu", "deprecated">, CXX11<"","deprecated">]; + let Args = [StringArgument<"Message", 1>]; } def Destructor : InheritableAttr { let Spellings = [GNU<"destructor">, CXX11<"gnu", "destructor">]; - let Args = [IntArgument<"Priority">]; + let Args = [IntArgument<"Priority", 1>]; } def ExtVectorType : Attr { @@ -362,7 +397,8 @@ def FastCall : InheritableAttr { } def Final : InheritableAttr { - let Spellings = []; + let Spellings = [Keyword<"final">, Keyword<"sealed">]; + let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>]; let SemaHandler = 0; } @@ -373,7 +409,7 @@ def MinSize : InheritableAttr { def Format : InheritableAttr { let Spellings = [GNU<"format">, CXX11<"gnu", "format">]; - let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">, + let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">, IntArgument<"FirstArg">]; } @@ -400,7 +436,7 @@ def IBOutlet : InheritableAttr { def IBOutletCollection : InheritableAttr { let Spellings = [GNU<"iboutletcollection">]; - let Args = [TypeArgument<"Interface">, SourceLocArgument<"InterfaceLoc">]; + let Args = [TypeArgument<"Interface", 1>]; } def Malloc : InheritableAttr { @@ -421,23 +457,13 @@ def MSABI : InheritableAttr { let Spellings = [GNU<"ms_abi">, CXX11<"gnu", "ms_abi">]; } -def MSP430Interrupt : InheritableAttr { +def MSP430Interrupt : InheritableAttr, TargetSpecificAttr { let Spellings = []; let Args = [UnsignedArgument<"Number">]; let SemaHandler = 0; } -def MBlazeInterruptHandler : InheritableAttr { - let Spellings = []; - let SemaHandler = 0; -} - -def MBlazeSaveVolatiles : InheritableAttr { - let Spellings = []; - let SemaHandler = 0; -} - -def Mips16 : InheritableAttr { +def Mips16 : InheritableAttr, TargetSpecificAttr { let Spellings = [GNU<"mips16">, CXX11<"gnu", "mips16">]; let Subjects = [Function]; } @@ -445,23 +471,20 @@ def Mips16 : InheritableAttr { def Mode : Attr { let Spellings = [GNU<"mode">, CXX11<"gnu", "mode">]; let Args = [IdentifierArgument<"Mode">]; - let ASTNode = 0; } def Naked : InheritableAttr { let Spellings = [GNU<"naked">, CXX11<"gnu", "naked">]; } -def NeonPolyVectorType : Attr { +def NeonPolyVectorType : TypeAttr { let Spellings = [GNU<"neon_polyvector_type">]; let Args = [IntArgument<"NumElements">]; - let ASTNode = 0; } -def NeonVectorType : Attr { +def NeonVectorType : TypeAttr { let Spellings = [GNU<"neon_vector_type">]; let Args = [IntArgument<"NumElements">]; - let ASTNode = 0; } def ReturnsTwice : InheritableAttr { @@ -480,7 +503,7 @@ def NoInline : InheritableAttr { let Spellings = [GNU<"noinline">, CXX11<"gnu", "noinline">]; } -def NoMips16 : InheritableAttr { +def NoMips16 : InheritableAttr, TargetSpecificAttr { let Spellings = [GNU<"nomips16">, CXX11<"gnu", "nomips16">]; let Subjects = [Function]; } @@ -517,7 +540,13 @@ def NoThrow : InheritableAttr { def NSBridged : InheritableAttr { let Spellings = [GNU<"ns_bridged">]; let Subjects = [Record]; - let Args = [IdentifierArgument<"BridgedType">]; + let Args = [IdentifierArgument<"BridgedType", 1>]; +} + +def ObjCBridge : InheritableAttr { + let Spellings = [GNU<"objc_bridge">]; + let Subjects = [Record]; + let Args = [IdentifierArgument<"BridgedType", 1>]; } def NSReturnsRetained : InheritableAttr { @@ -562,14 +591,14 @@ def ObjCNSObject : InheritableAttr { let Spellings = [GNU<"NSObject">]; } -def ObjCPreciseLifetime : Attr { +def ObjCPreciseLifetime : InheritableAttr { let Spellings = [GNU<"objc_precise_lifetime">]; let Subjects = [Var]; } -def ObjCReturnsInnerPointer : Attr { +def ObjCReturnsInnerPointer : InheritableAttr { let Spellings = [GNU<"objc_returns_inner_pointer">]; - let Subjects = [ObjCMethod]; + let Subjects = [ObjCMethod, ObjCProperty]; } def ObjCRequiresSuper : InheritableAttr { @@ -577,7 +606,7 @@ def ObjCRequiresSuper : InheritableAttr { let Subjects = [ObjCMethod]; } -def ObjCRootClass : Attr { +def ObjCRootClass : InheritableAttr { let Spellings = [GNU<"objc_root_class">]; let Subjects = [ObjCInterface]; } @@ -599,6 +628,7 @@ def Ownership : InheritableAttr { ["ownership_holds", "ownership_returns", "ownership_takes"], ["Holds", "Returns", "Takes"]>, StringArgument<"Module">, VariadicUnsignedArgument<"Args">]; + let HasCustomParsing = 1; } def Packed : InheritableAttr { @@ -635,11 +665,6 @@ def ReqdWorkGroupSize : InheritableAttr { UnsignedArgument<"ZDim">]; } -def Endian : InheritableAttr { - let Spellings = [GNU<"endian">]; - let Args = [IdentifierArgument<"platform">]; -} - def WorkGroupSizeHint : InheritableAttr { let Spellings = [GNU<"work_group_size_hint">]; let Args = [UnsignedArgument<"XDim">, @@ -687,7 +712,7 @@ def TransparentUnion : InheritableAttr { def Unavailable : InheritableAttr { let Spellings = [GNU<"unavailable">]; - let Args = [StringArgument<"Message">]; + let Args = [StringArgument<"Message", 1>]; } def ArcWeakrefUnavailable : InheritableAttr { @@ -695,13 +720,12 @@ def ArcWeakrefUnavailable : InheritableAttr { let Subjects = [ObjCInterface]; } -def ObjCGC : Attr { +def ObjCGC : TypeAttr { let Spellings = [GNU<"objc_gc">]; let Args = [IdentifierArgument<"Kind">]; - let ASTNode = 0; } -def ObjCOwnership : Attr { +def ObjCOwnership : InheritableAttr { let Spellings = [GNU<"objc_ownership">]; let Args = [IdentifierArgument<"Kind">]; let ASTNode = 0; @@ -726,15 +750,14 @@ def Uuid : InheritableAttr { let Subjects = [CXXRecord]; } -def VectorSize : Attr { +def VectorSize : TypeAttr { let Spellings = [GNU<"vector_size">, CXX11<"gnu", "vector_size">]; let Args = [ExprArgument<"NumBytes">]; - let ASTNode = 0; } def VecTypeHint : InheritableAttr { let Spellings = [GNU<"vec_type_hint">]; - let Args = [TypeArgument<"TypeHint">, SourceLocArgument<"TypeLoc">]; + let Args = [TypeArgument<"TypeHint">]; } def Visibility : InheritableAttr { @@ -758,6 +781,11 @@ def VecReturn : InheritableAttr { let Subjects = [CXXRecord]; } +def WarnUnused : InheritableAttr { + let Spellings = [GNU<"warn_unused">]; + let Subjects = [Record]; +} + def WarnUnusedResult : InheritableAttr { let Spellings = [GNU<"warn_unused_result">, CXX11<"clang", "warn_unused_result">, @@ -774,16 +802,20 @@ def WeakImport : InheritableAttr { def WeakRef : InheritableAttr { let Spellings = [GNU<"weakref">, CXX11<"gnu", "weakref">]; + // A WeakRef that has an argument is treated as being an AliasAttr + let Args = [StringArgument<"Aliasee", 1>]; } -def X86ForceAlignArgPointer : InheritableAttr { +def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr { let Spellings = []; } // Attribute to disable AddressSanitizer (or equivalent) checks. def NoSanitizeAddress : InheritableAttr { let Spellings = [GNU<"no_address_safety_analysis">, - GNU<"no_sanitize_address">]; + GNU<"no_sanitize_address">, + CXX11<"gnu", "no_address_safety_analysis">, + CXX11<"gnu", "no_sanitize_address">]; } // Attribute to disable ThreadSanitizer checks. @@ -860,6 +892,20 @@ def SharedLockFunction : InheritableAttr { let TemplateDependent = 1; } +def AssertExclusiveLock : InheritableAttr { + let Spellings = [GNU<"assert_exclusive_lock">]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; + let TemplateDependent = 1; +} + +def AssertSharedLock : InheritableAttr { + let Spellings = [GNU<"assert_shared_lock">]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; + let TemplateDependent = 1; +} + // The first argument is an integer or boolean value specifying the return value // of a successful lock acquisition. def ExclusiveTrylockFunction : InheritableAttr { @@ -913,6 +959,56 @@ def SharedLocksRequired : InheritableAttr { let TemplateDependent = 1; } +// C/C++ consumed attributes. + +def Consumable : InheritableAttr { + let Spellings = [GNU<"consumable">]; + let Subjects = [CXXRecord]; + let Args = [EnumArgument<"DefaultState", "ConsumedState", + ["unknown", "consumed", "unconsumed"], + ["Unknown", "Consumed", "Unconsumed"]>]; +} + +def CallableWhen : InheritableAttr { + let Spellings = [GNU<"callable_when">]; + let Subjects = [CXXMethod]; + let Args = [VariadicEnumArgument<"CallableState", "ConsumedState", + ["unknown", "consumed", "unconsumed"], + ["Unknown", "Consumed", "Unconsumed"]>]; +} + +def ParamTypestate : InheritableAttr { + let Spellings = [GNU<"param_typestate">]; + let Subjects = [ParmVar]; + let Args = [EnumArgument<"ParamState", "ConsumedState", + ["unknown", "consumed", "unconsumed"], + ["Unknown", "Consumed", "Unconsumed"]>]; +} + +def ReturnTypestate : InheritableAttr { + let Spellings = [GNU<"return_typestate">]; + let Subjects = [Function, ParmVar]; + let Args = [EnumArgument<"State", "ConsumedState", + ["unknown", "consumed", "unconsumed"], + ["Unknown", "Consumed", "Unconsumed"]>]; +} + +def SetTypestate : InheritableAttr { + let Spellings = [GNU<"set_typestate">]; + let Subjects = [CXXMethod]; + let Args = [EnumArgument<"NewState", "ConsumedState", + ["unknown", "consumed", "unconsumed"], + ["Unknown", "Consumed", "Unconsumed"]>]; +} + +def TestTypestate : InheritableAttr { + let Spellings = [GNU<"test_typestate">]; + let Subjects = [CXXMethod]; + let Args = [EnumArgument<"TestState", "ConsumedState", + ["consumed", "unconsumed"], + ["Consumed", "Unconsumed"]>]; +} + // Type safety attributes for `void *' pointers and type tags. def ArgumentWithTypeTag : InheritableAttr { @@ -923,6 +1019,7 @@ def ArgumentWithTypeTag : InheritableAttr { UnsignedArgument<"TypeTagIdx">, BoolArgument<"IsPointer">]; let Subjects = [Function]; + let HasCustomParsing = 1; } def TypeTagForDatatype : InheritableAttr { @@ -932,11 +1029,12 @@ def TypeTagForDatatype : InheritableAttr { BoolArgument<"LayoutCompatible">, BoolArgument<"MustBeNull">]; let Subjects = [Var]; + let HasCustomParsing = 1; } // Microsoft-related attributes -def MsProperty : Attr { +def MsProperty : IgnoredAttr { let Spellings = [Declspec<"property">]; } @@ -944,11 +1042,11 @@ def MsStruct : InheritableAttr { let Spellings = [Declspec<"ms_struct">]; } -def DLLExport : InheritableAttr { +def DLLExport : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"dllexport">]; } -def DLLImport : InheritableAttr { +def DLLImport : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"dllimport">]; } @@ -956,18 +1054,30 @@ def ForceInline : InheritableAttr { let Spellings = [Keyword<"__forceinline">]; } +def SelectAny : InheritableAttr { + let Spellings = [Declspec<"selectany">]; +} + def Win64 : InheritableAttr { let Spellings = [Keyword<"__w64">]; } -def Ptr32 : InheritableAttr { +def Ptr32 : TypeAttr { let Spellings = [Keyword<"__ptr32">]; } -def Ptr64 : InheritableAttr { +def Ptr64 : TypeAttr { let Spellings = [Keyword<"__ptr64">]; } +def SPtr : TypeAttr { + let Spellings = [Keyword<"__sptr">]; +} + +def UPtr : TypeAttr { + let Spellings = [Keyword<"__uptr">]; +} + class MSInheritanceAttr : InheritableAttr; def SingleInheritance : MSInheritanceAttr { diff --git a/contrib/llvm/tools/clang/include/clang/Basic/AttrKinds.h b/contrib/llvm/tools/clang/include/clang/Basic/AttrKinds.h index bd090ec..7c4e2c7 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/AttrKinds.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/AttrKinds.h @@ -24,7 +24,7 @@ enum Kind { #define ATTR(X) X, #define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X, #define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X, -#define LAST_MS_INHERITABLE_ATTR(X) X, LAST_MS_INHERITABLE = X, +#define LAST_MS_INHERITANCE_ATTR(X) X, LAST_MS_INHERITANCE = X, #include "clang/Basic/AttrList.inc" NUM_ATTRS }; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def index 48bf5db..55c6ed7 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def @@ -25,6 +25,7 @@ // c -> char // s -> short // i -> int +// h -> half // f -> float // d -> double // z -> size_t @@ -91,6 +92,10 @@ # define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS) #endif +#if defined(BUILTIN) && !defined(LANGBUILTIN) +# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS) +#endif + // Standard libc/libm functions: BUILTIN(__builtin_atan2 , "ddd" , "Fnc") BUILTIN(__builtin_atan2f, "fff" , "Fnc") @@ -238,8 +243,8 @@ BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc") BUILTIN(__builtin_nextafter , "ddd", "Fnc") BUILTIN(__builtin_nextafterf, "fff", "Fnc") BUILTIN(__builtin_nextafterl, "LdLdLd", "Fnc") -BUILTIN(__builtin_nexttoward , "ddd", "Fnc") -BUILTIN(__builtin_nexttowardf, "fff", "Fnc") +BUILTIN(__builtin_nexttoward , "ddLd", "Fnc") +BUILTIN(__builtin_nexttowardf, "ffLd", "Fnc") BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fnc") BUILTIN(__builtin_remainder , "ddd", "Fnc") BUILTIN(__builtin_remainderf, "fff", "Fnc") @@ -487,6 +492,7 @@ BUILTIN(__builtin_trap, "v", "nr") BUILTIN(__builtin_debugtrap, "v", "n") BUILTIN(__builtin_unreachable, "v", "nr") BUILTIN(__builtin_shufflevector, "v." , "nc") +BUILTIN(__builtin_convertvector, "v." , "nct") BUILTIN(__builtin_alloca, "v*z" , "n") // "Overloaded" Atomic operator builtins. These are overloaded to support data @@ -668,11 +674,11 @@ BUILTIN(__builtin_abort, "v", "Fnr") BUILTIN(__builtin_index, "c*cC*i", "Fn") BUILTIN(__builtin_rindex, "c*cC*i", "Fn") -// Microsoft builtins. -BUILTIN(__assume, "vb", "n") -BUILTIN(__noop, "v.", "n") -BUILTIN(__debugbreak, "v", "n") - +// Microsoft builtins. These are only active with -fms-extensions. +LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__noop, "v.", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES) // C99 library functions // C99 stdlib.h @@ -720,48 +726,47 @@ LIBBUILTIN(vscanf, "icC*Ra", "fS:0:", "stdio.h", ALL_LANGUAGES) LIBBUILTIN(vfscanf, "iP*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES) LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES) // C99 +#undef setjmp +LIBBUILTIN(setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) LIBBUILTIN(longjmp, "vJi", "fr", "setjmp.h", ALL_LANGUAGES) -// Non-C library functions -// FIXME: Non-C-standard stuff shouldn't be builtins in non-GNU mode! -LIBBUILTIN(alloca, "v*z", "f", "stdlib.h", ALL_LANGUAGES) +// Non-C library functions, active in GNU mode only. +LIBBUILTIN(alloca, "v*z", "f", "stdlib.h", ALL_GNU_LANGUAGES) // POSIX string.h -LIBBUILTIN(stpcpy, "c*c*cC*", "f", "string.h", ALL_LANGUAGES) -LIBBUILTIN(stpncpy, "c*c*cC*z", "f", "string.h", ALL_LANGUAGES) -LIBBUILTIN(strdup, "c*cC*", "f", "string.h", ALL_LANGUAGES) -LIBBUILTIN(strndup, "c*cC*z", "f", "string.h", ALL_LANGUAGES) +LIBBUILTIN(stpcpy, "c*c*cC*", "f", "string.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(stpncpy, "c*c*cC*z", "f", "string.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(strdup, "c*cC*", "f", "string.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(strndup, "c*cC*z", "f", "string.h", ALL_GNU_LANGUAGES) // POSIX strings.h -LIBBUILTIN(index, "c*cC*i", "f", "strings.h", ALL_LANGUAGES) -LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_LANGUAGES) -LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_LANGUAGES) +LIBBUILTIN(index, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_GNU_LANGUAGES) // In some systems str[n]casejmp is a macro that expands to _str[n]icmp. // We undefine then here to avoid wrong name. #undef strcasecmp #undef strncasecmp -LIBBUILTIN(strcasecmp, "icC*cC*", "f", "strings.h", ALL_LANGUAGES) -LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_LANGUAGES) +LIBBUILTIN(strcasecmp, "icC*cC*", "f", "strings.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_GNU_LANGUAGES) // POSIX unistd.h -LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_LANGUAGES) -LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_LANGUAGES) +LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_GNU_LANGUAGES) // POSIX setjmp.h // In some systems setjmp is a macro that expands to _setjmp. We undefine // it here to avoid having two identical LIBBUILTIN entries. -#undef setjmp -LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) -LIBBUILTIN(__sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_LANGUAGES) -LIBBUILTIN(setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) -LIBBUILTIN(sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_LANGUAGES) -LIBBUILTIN(setjmp_syscall, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) -LIBBUILTIN(savectx, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) -LIBBUILTIN(qsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) -LIBBUILTIN(getcontext, "iK*", "fj", "setjmp.h", ALL_LANGUAGES) - -LIBBUILTIN(_longjmp, "vJi", "fr", "setjmp.h", ALL_LANGUAGES) -LIBBUILTIN(siglongjmp, "vSJi", "fr", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(__sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(sigsetjmp, "iSJi", "fj", "setjmp.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(setjmp_syscall, "iJ", "fj", "setjmp.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(savectx, "iJ", "fj", "setjmp.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(qsetjmp, "iJ", "fj", "setjmp.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(getcontext, "iK*", "fj", "setjmp.h", ALL_GNU_LANGUAGES) + +LIBBUILTIN(_longjmp, "vJi", "fr", "setjmp.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(siglongjmp, "vSJi", "fr", "setjmp.h", ALL_GNU_LANGUAGES) // non-standard but very common -LIBBUILTIN(strlcpy, "zc*cC*z", "f", "string.h", ALL_LANGUAGES) -LIBBUILTIN(strlcat, "zc*cC*z", "f", "string.h", ALL_LANGUAGES) +LIBBUILTIN(strlcpy, "zc*cC*z", "f", "string.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(strlcat, "zc*cC*z", "f", "string.h", ALL_GNU_LANGUAGES) // id objc_msgSend(id, SEL, ...) LIBBUILTIN(objc_msgSend, "GGH.", "f", "objc/message.h", OBJC_LANG) // long double objc_msgSend_fpret(id self, SEL op, ...) @@ -816,109 +821,321 @@ LIBBUILTIN(NSLog, "vG.", "fp:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG) LIBBUILTIN(NSLogv, "vGa", "fP:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG) // Builtin math library functions -LIBBUILTIN(acos, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(acosl, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(acosf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(atan2, "ddd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(atan2f, "fff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(atan2l, "LdLdLd", "fne", "math.h", ALL_LANGUAGES) -LIBBUILTIN(asin, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(asinl, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(asinf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(abs, "ii", "fnc", "stdlib.h", ALL_LANGUAGES) +LIBBUILTIN(labs, "LiLi", "fnc", "stdlib.h", ALL_LANGUAGES) +LIBBUILTIN(llabs, "LLiLLi", "fnc", "stdlib.h", ALL_LANGUAGES) -LIBBUILTIN(atan, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(atanl, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(atanf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(copysign, "ddd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(copysignf, "fff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(copysignl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES) -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(fabs, "dd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fabsf, "ff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fabsl, "LdLd", "fnc", "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(fmod, "ddd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmodf, "fff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmodl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES) -LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES) -LIBBUILTIN(cimagf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) -LIBBUILTIN(cimagl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(frexp, "ddi*", "fn", "math.h", ALL_LANGUAGES) +LIBBUILTIN(frexpf, "ffi*", "fn", "math.h", ALL_LANGUAGES) +LIBBUILTIN(frexpl, "LdLdi*", "fn", "math.h", ALL_LANGUAGES) -LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES) -LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) -LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(ldexp, "ddi", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(ldexpf, "ffi", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(ldexpl, "LdLdi", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(modf, "ddd*", "fn", "math.h", ALL_LANGUAGES) +LIBBUILTIN(modff, "fff*", "fn", "math.h", ALL_LANGUAGES) +LIBBUILTIN(modfl, "LdLdLd*", "fn", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(nan, "dcC*", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nanf, "fcC*", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nanl, "LdcC*", "fnc", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(pow, "ddd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(powf, "fff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(powl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(acos, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(acosf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(acosl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(acosh, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(acoshf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(acoshl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(asin, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(asinf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(asinl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(asinh, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(asinhf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(asinhl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(atan, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(atanf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(atanl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(atanh, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(atanhf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(atanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(cbrt, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(cbrtf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(cbrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(ceil, "dd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(ceilf, "ff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(ceill, "LdLd", "fnc", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(cos, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(cosf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(cosl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(cosh, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(coshf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(coshl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(erf, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(erff, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(erfl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(erfc, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(erfcf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(erfcl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(exp, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(expf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(expl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(exp2, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(exp2f, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(exp2l, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(expm1, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(expm1f, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(expm1l, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(fdim, "ddd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fdimf, "fff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fdiml, "LdLdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(floor, "dd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(floorf, "ff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(floorl, "LdLd", "fnc", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(fma, "dddd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmaf, "ffff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmal, "LdLdLdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(fmax, "ddd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmaxf, "fff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmaxl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(fmin, "ddd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fminf, "fff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fminl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(hypot, "ddd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(hypotf, "fff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(hypotl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(ilogb, "id", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(ilogbf, "if", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(ilogbl, "iLd", "fne", "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(lgamma, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(lgammaf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(lgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES) -LIBBUILTIN(cos, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(cosl, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(cosf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(llrint, "LLid", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(llrintf, "LLif", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(llrintl, "LLiLd", "fne", "math.h", ALL_LANGUAGES) -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(llround, "LLid", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(llroundf, "LLif", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(llroundl, "LLiLd", "fne", "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(log, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(logf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(logl, "LdLd", "fne", "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(log10, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(log10f, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(log10l, "LdLd", "fne", "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(log1p, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(log1pf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(log1pl, "LdLd", "fne", "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(log2, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(log2f, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(log2l, "LdLd", "fne", "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(logb, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(logbf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(logbl, "LdLd", "fne", "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(lrint, "Lid", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(lrintf, "Lif", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(lrintl, "LiLd", "fne", "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(lround, "Lid", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(lroundf, "Lif", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(lroundl, "LiLd", "fne", "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", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nearbyintf, "ff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nearbyintl, "LdLd", "fnc", "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(nextafter, "ddd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nextafterf, "fff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nextafterl, "LdLdLd", "fne", "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(nexttoward, "ddLd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nexttowardf, "ffLd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(nexttowardl, "LdLdLd", "fne", "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(remainder, "ddd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(remainderf, "fff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(remainderl, "LdLdLd", "fne", "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(rint, "dd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(rintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES) -LIBBUILTIN(sin, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(sinl, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(sinf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(round, "dd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(roundf, "ff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(roundl, "LdLd", "fnc", "math.h", ALL_LANGUAGES) -LIBBUILTIN(sqrt, "dd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(sqrtl, "LdLd", "fe", "math.h", ALL_LANGUAGES) -LIBBUILTIN(sqrtf, "ff", "fe", "math.h", ALL_LANGUAGES) +LIBBUILTIN(scalbln, "ddLi", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(scalblnf, "ffLi", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(scalblnl, "LdLdLi", "fne", "math.h", ALL_LANGUAGES) -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(scalbn, "ddi", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(scalbnf, "ffi", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(scalbnl, "LdLdi", "fne", "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) +LIBBUILTIN(sin, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(sinf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(sinl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(sinh, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(sinhf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(sinhl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(sqrt, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(sqrtf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(sqrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(tan, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(tanf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(tanl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(tanh, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(tanhf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(tanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(tgamma, "dd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(tgammaf, "ff", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(tgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(trunc, "dd", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(truncf, "ff", "fnc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(truncl, "LdLd", "fnc", "math.h", ALL_LANGUAGES) + +LIBBUILTIN(cabs, "dXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cabsf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cabsl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(cacos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cacosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cacosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(cacosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cacoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cacoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(carg, "dXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cargf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cargl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(casin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(casinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(casinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(casinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(casinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(casinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(catan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(catanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(catanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(catanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(catanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(catanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(ccos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(ccosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(ccosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(ccosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(ccoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(ccoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(cexp, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cexpf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cexpl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cimagf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cimagl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(conj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(conjf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(conjl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(clog, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(clogf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(clogl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(cproj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cprojf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cprojl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(cpow, "XdXdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cpowf, "XfXfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(cpowl, "XLdXLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(csin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(csinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(csinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(csinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(csinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(csinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(csqrt, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(csqrtf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(csqrtl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(ctan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(ctanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(ctanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) + +LIBBUILTIN(ctanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(ctanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) +LIBBUILTIN(ctanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) // Blocks runtime Builtin math library functions LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES) @@ -929,14 +1146,40 @@ LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES) BUILTIN(__builtin_annotation, "v.", "tn") // Multiprecision Arithmetic Builtins. +BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n") BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n") BUILTIN(__builtin_addc, "UiUiCUiCUiCUi*", "n") BUILTIN(__builtin_addcl, "ULiULiCULiCULiCULi*", "n") BUILTIN(__builtin_addcll, "ULLiULLiCULLiCULLiCULLi*", "n") +BUILTIN(__builtin_subcb, "UcUcCUcCUcCUc*", "n") BUILTIN(__builtin_subcs, "UsUsCUsCUsCUs*", "n") BUILTIN(__builtin_subc, "UiUiCUiCUiCUi*", "n") BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n") BUILTIN(__builtin_subcll, "ULLiULLiCULLiCULLiCULLi*", "n") +// Checked Arithmetic Builtins for Security. +BUILTIN(__builtin_uadd_overflow, "bUiCUiCUi*", "n") +BUILTIN(__builtin_uaddl_overflow, "bULiCULiCULi*", "n") +BUILTIN(__builtin_uaddll_overflow, "bULLiCULLiCULLi*", "n") +BUILTIN(__builtin_usub_overflow, "bUiCUiCUi*", "n") +BUILTIN(__builtin_usubl_overflow, "bULiCULiCULi*", "n") +BUILTIN(__builtin_usubll_overflow, "bULLiCULLiCULLi*", "n") +BUILTIN(__builtin_umul_overflow, "bUiCUiCUi*", "n") +BUILTIN(__builtin_umull_overflow, "bULiCULiCULi*", "n") +BUILTIN(__builtin_umulll_overflow, "bULLiCULLiCULLi*", "n") +BUILTIN(__builtin_sadd_overflow, "bSiCSiCSi*", "n") +BUILTIN(__builtin_saddl_overflow, "bSLiCSLiCSLi*", "n") +BUILTIN(__builtin_saddll_overflow, "bSLLiCSLLiCSLLi*", "n") +BUILTIN(__builtin_ssub_overflow, "bSiCSiCSi*", "n") +BUILTIN(__builtin_ssubl_overflow, "bSLiCSLiCSLi*", "n") +BUILTIN(__builtin_ssubll_overflow, "bSLLiCSLLiCSLLi*", "n") +BUILTIN(__builtin_smul_overflow, "bSiCSiCSi*", "n") +BUILTIN(__builtin_smull_overflow, "bSLiCSLiCSLi*", "n") +BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "n") + +// Clang builtins (not available in GCC). +BUILTIN(__builtin_addressof, "v*v&", "nct") + #undef BUILTIN #undef LIBBUILTIN +#undef LANGBUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h index cfcbcdb..9756f21 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h @@ -31,10 +31,14 @@ namespace clang { class LangOptions; enum LanguageID { - C_LANG = 0x1, // builtin for c only. - CXX_LANG = 0x2, // builtin for cplusplus only. - OBJC_LANG = 0x4, // builtin for objective-c and objective-c++ - ALL_LANGUAGES = (C_LANG|CXX_LANG|OBJC_LANG) //builtin is for all languages. + GNU_LANG = 0x1, // builtin requires GNU mode. + C_LANG = 0x2, // builtin for c only. + CXX_LANG = 0x4, // builtin for cplusplus only. + OBJC_LANG = 0x8, // builtin for objective-c and objective-c++ + MS_LANG = 0x10, // builtin requires MS mode. + ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages. + ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode. + ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode. }; namespace Builtin { @@ -73,9 +77,8 @@ public: /// such. void InitializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts); - /// \brief Popular the vector with the names of all of the builtins. - void GetBuiltinNames(SmallVectorImpl<const char *> &Names, - bool NoBuiltins); + /// \brief Populate the vector with the names of all of the builtins. + void GetBuiltinNames(SmallVectorImpl<const char *> &Names); /// \brief Return the identifier name for the specified builtin, /// e.g. "__builtin_abs". @@ -170,6 +173,10 @@ public: private: const Info &GetRecord(unsigned ID) const; + + /// \brief Is this builtin supported according to the given language options? + bool BuiltinIsSupported(const Builtin::Info &BuiltinInfo, + const LangOptions &LangOpts); }; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsAArch64.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsAArch64.def index 768e4bb..aafd202 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsAArch64.def @@ -16,3 +16,10 @@ // In libgcc BUILTIN(__clear_cache, "vv*v*", "i") +// NEON +#define GET_NEON_AARCH64_BUILTINS +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_AARCH64_BUILTINS +#undef GET_NEON_BUILTINS + +#undef BUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def index f1e3dfc..21bb892 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def @@ -15,7 +15,7 @@ // The format of this database matches clang/Basic/Builtins.def. // In libgcc -BUILTIN(__clear_cache, "v.", "i") +BUILTIN(__clear_cache, "vv*v*", "i") BUILTIN(__builtin_thread_pointer, "v*", "") // Saturating arithmetic @@ -24,10 +24,14 @@ BUILTIN(__builtin_arm_qsub, "iii", "nc") BUILTIN(__builtin_arm_ssat, "iiUi", "nc") BUILTIN(__builtin_arm_usat, "UiUiUi", "nc") -// Store and load exclusive doubleword +// Store and load exclusive BUILTIN(__builtin_arm_ldrexd, "LLUiv*", "") BUILTIN(__builtin_arm_strexd, "iLLUiv*", "") +BUILTIN(__builtin_arm_ldrex, "v.", "t") +BUILTIN(__builtin_arm_strex, "i.", "t") +BUILTIN(__builtin_arm_clrex, "v", "") + // VFP BUILTIN(__builtin_arm_get_fpscr, "Ui", "nc") BUILTIN(__builtin_arm_set_fpscr, "vUi", "nc") @@ -44,6 +48,23 @@ BUILTIN(__builtin_arm_cdp2, "vUiUiUiUiUiUi", "") BUILTIN(__builtin_arm_mcrr, "vUiUiUiUiUi", "") BUILTIN(__builtin_arm_mcrr2, "vUiUiUiUiUi", "") +// CRC32 +BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc") +BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc") +BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc") +BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc") +BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc") +BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc") +BUILTIN(__builtin_arm_crc32d, "UiUiLLUi", "nc") +BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc") + +// HINT +BUILTIN(__builtin_arm_sevl, "v", "") + +// Data barrier +BUILTIN(__builtin_arm_dmb, "vUi", "nc") +BUILTIN(__builtin_arm_dsb, "vUi", "nc") + // NEON #define GET_NEON_BUILTINS #include "clang/Basic/arm_neon.inc" diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsMips.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsMips.def index 43fb907..e435d52 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsMips.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsMips.def @@ -185,4 +185,716 @@ BUILTIN(__builtin_mips_subu_s_ph, "V2sV2sV2s", "n") BUILTIN(__builtin_mips_subuh_qb, "V4ScV4ScV4Sc", "nc") BUILTIN(__builtin_mips_subuh_r_qb, "V4ScV4ScV4Sc", "nc") +// MIPS MSA + +BUILTIN(__builtin_msa_add_a_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_add_a_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_add_a_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_add_a_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_adds_a_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_adds_a_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_adds_a_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_adds_a_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_adds_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_adds_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_adds_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_adds_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_adds_u_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_adds_u_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_adds_u_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_adds_u_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_addv_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_addv_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_addv_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_addv_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_addvi_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_addvi_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_addvi_w, "V4iV4iIUi", "nc") +BUILTIN(__builtin_msa_addvi_d, "V2LLiV2LLiIUi", "nc") + +BUILTIN(__builtin_msa_and_v, "V16UcV16UcV16Uc", "nc") + +BUILTIN(__builtin_msa_andi_b, "V16UcV16UcIUi", "nc") + +BUILTIN(__builtin_msa_asub_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_asub_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_asub_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_asub_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_asub_u_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_asub_u_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_asub_u_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_asub_u_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_ave_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_ave_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_ave_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_ave_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_ave_u_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_ave_u_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_ave_u_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_ave_u_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_aver_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_aver_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_aver_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_aver_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_aver_u_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_aver_u_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_aver_u_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_aver_u_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_bclr_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_bclr_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_bclr_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_bclr_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_bclri_b, "V16UcV16UcIUi", "nc") +BUILTIN(__builtin_msa_bclri_h, "V8UsV8UsIUi", "nc") +BUILTIN(__builtin_msa_bclri_w, "V4UiV4UiIUi", "nc") +BUILTIN(__builtin_msa_bclri_d, "V2ULLiV2ULLiIUi", "nc") + +BUILTIN(__builtin_msa_binsl_b, "V16UcV16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_binsl_h, "V8UsV8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_binsl_w, "V4UiV4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_binsl_d, "V2ULLiV2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_binsli_b, "V16UcV16UcV16UcIUi", "nc") +BUILTIN(__builtin_msa_binsli_h, "V8UsV8UsV8UsIUi", "nc") +BUILTIN(__builtin_msa_binsli_w, "V4UiV4UiV4UiIUi", "nc") +BUILTIN(__builtin_msa_binsli_d, "V2ULLiV2ULLiV2ULLiIUi", "nc") + +BUILTIN(__builtin_msa_binsr_b, "V16UcV16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_binsr_h, "V8UsV8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_binsr_w, "V4UiV4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_binsr_d, "V2ULLiV2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_binsri_b, "V16UcV16UcV16UcIUi", "nc") +BUILTIN(__builtin_msa_binsri_h, "V8UsV8UsV8UsIUi", "nc") +BUILTIN(__builtin_msa_binsri_w, "V4UiV4UiV4UiIUi", "nc") +BUILTIN(__builtin_msa_binsri_d, "V2ULLiV2ULLiV2ULLiIUi", "nc") + +BUILTIN(__builtin_msa_bmnz_v, "V16UcV16UcV16UcV16Uc", "nc") + +BUILTIN(__builtin_msa_bmnzi_b, "V16UcV16UcV16UcIUi", "nc") + +BUILTIN(__builtin_msa_bmz_v, "V16UcV16UcV16UcV16Uc", "nc") + +BUILTIN(__builtin_msa_bmzi_b, "V16UcV16UcV16UcIUi", "nc") + +BUILTIN(__builtin_msa_bneg_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_bneg_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_bneg_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_bneg_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_bnegi_b, "V16UcV16UcIUi", "nc") +BUILTIN(__builtin_msa_bnegi_h, "V8UsV8UsIUi", "nc") +BUILTIN(__builtin_msa_bnegi_w, "V4UiV4UiIUi", "nc") +BUILTIN(__builtin_msa_bnegi_d, "V2ULLiV2ULLiIUi", "nc") + +BUILTIN(__builtin_msa_bnz_b, "iV16Uc", "nc") +BUILTIN(__builtin_msa_bnz_h, "iV8Us", "nc") +BUILTIN(__builtin_msa_bnz_w, "iV4Ui", "nc") +BUILTIN(__builtin_msa_bnz_d, "iV2ULLi", "nc") + +BUILTIN(__builtin_msa_bnz_v, "iV16Uc", "nc") + +BUILTIN(__builtin_msa_bsel_v, "V16UcV16UcV16UcV16Uc", "nc") + +BUILTIN(__builtin_msa_bseli_b, "V16UcV16UcV16UcIUi", "nc") + +BUILTIN(__builtin_msa_bset_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_bset_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_bset_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_bset_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_bseti_b, "V16UcV16UcIUi", "nc") +BUILTIN(__builtin_msa_bseti_h, "V8UsV8UsIUi", "nc") +BUILTIN(__builtin_msa_bseti_w, "V4UiV4UiIUi", "nc") +BUILTIN(__builtin_msa_bseti_d, "V2ULLiV2ULLiIUi", "nc") + +BUILTIN(__builtin_msa_bz_b, "iV16Uc", "nc") +BUILTIN(__builtin_msa_bz_h, "iV8Us", "nc") +BUILTIN(__builtin_msa_bz_w, "iV4Ui", "nc") +BUILTIN(__builtin_msa_bz_d, "iV2ULLi", "nc") + +BUILTIN(__builtin_msa_bz_v, "iV16Uc", "nc") + +BUILTIN(__builtin_msa_ceq_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_ceq_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_ceq_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_ceq_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_ceqi_b, "V16ScV16ScISi", "nc") +BUILTIN(__builtin_msa_ceqi_h, "V8SsV8SsISi", "nc") +BUILTIN(__builtin_msa_ceqi_w, "V4SiV4SiISi", "nc") +BUILTIN(__builtin_msa_ceqi_d, "V2SLLiV2SLLiISi", "nc") + +BUILTIN(__builtin_msa_cfcmsa, "iIi", "n") + +BUILTIN(__builtin_msa_cle_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_cle_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_cle_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_cle_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_cle_u_b, "V16ScV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_cle_u_h, "V8SsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_cle_u_w, "V4SiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_cle_u_d, "V2SLLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_clei_s_b, "V16ScV16ScISi", "nc") +BUILTIN(__builtin_msa_clei_s_h, "V8SsV8SsISi", "nc") +BUILTIN(__builtin_msa_clei_s_w, "V4SiV4SiISi", "nc") +BUILTIN(__builtin_msa_clei_s_d, "V2SLLiV2SLLiISi", "nc") + +BUILTIN(__builtin_msa_clei_u_b, "V16ScV16UcIUi", "nc") +BUILTIN(__builtin_msa_clei_u_h, "V8SsV8UsIUi", "nc") +BUILTIN(__builtin_msa_clei_u_w, "V4SiV4UiIUi", "nc") +BUILTIN(__builtin_msa_clei_u_d, "V2SLLiV2ULLiIUi", "nc") + +BUILTIN(__builtin_msa_clt_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_clt_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_clt_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_clt_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_clt_u_b, "V16ScV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_clt_u_h, "V8SsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_clt_u_w, "V4SiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_clt_u_d, "V2SLLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_clti_s_b, "V16ScV16ScISi", "nc") +BUILTIN(__builtin_msa_clti_s_h, "V8SsV8SsISi", "nc") +BUILTIN(__builtin_msa_clti_s_w, "V4SiV4SiISi", "nc") +BUILTIN(__builtin_msa_clti_s_d, "V2SLLiV2SLLiISi", "nc") + +BUILTIN(__builtin_msa_clti_u_b, "V16ScV16UcIUi", "nc") +BUILTIN(__builtin_msa_clti_u_h, "V8SsV8UsIUi", "nc") +BUILTIN(__builtin_msa_clti_u_w, "V4SiV4UiIUi", "nc") +BUILTIN(__builtin_msa_clti_u_d, "V2SLLiV2ULLiIUi", "nc") + +BUILTIN(__builtin_msa_copy_s_b, "iV16ScIUi", "nc") +BUILTIN(__builtin_msa_copy_s_h, "iV8SsIUi", "nc") +BUILTIN(__builtin_msa_copy_s_w, "iV4SiIUi", "nc") +BUILTIN(__builtin_msa_copy_s_d, "LLiV2SLLiIUi", "nc") + +BUILTIN(__builtin_msa_copy_u_b, "iV16UcIUi", "nc") +BUILTIN(__builtin_msa_copy_u_h, "iV8UsIUi", "nc") +BUILTIN(__builtin_msa_copy_u_w, "iV4UiIUi", "nc") +BUILTIN(__builtin_msa_copy_u_d, "LLiV2ULLiIUi", "nc") + +BUILTIN(__builtin_msa_ctcmsa, "vIii", "n") + +BUILTIN(__builtin_msa_div_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_div_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_div_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_div_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_div_u_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_div_u_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_div_u_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_div_u_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_dotp_s_h, "V8SsV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_dotp_s_w, "V4SiV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_dotp_s_d, "V2SLLiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_dotp_u_h, "V8UsV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_dotp_u_w, "V4UiV8UsV8Us", "nc") +BUILTIN(__builtin_msa_dotp_u_d, "V2ULLiV4UiV4Ui", "nc") + +BUILTIN(__builtin_msa_dpadd_s_h, "V8SsV8SsV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_dpadd_s_w, "V4SiV4SiV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_dpadd_s_d, "V2SLLiV2SLLiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_dpadd_u_h, "V8UsV8UsV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_dpadd_u_w, "V4UiV4UiV8UsV8Us", "nc") +BUILTIN(__builtin_msa_dpadd_u_d, "V2ULLiV2ULLiV4UiV4Ui", "nc") + +BUILTIN(__builtin_msa_dpsub_s_h, "V8SsV8SsV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_dpsub_s_w, "V4SiV4SiV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_dpsub_s_d, "V2SLLiV2SLLiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_dpsub_u_h, "V8UsV8UsV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_dpsub_u_w, "V4UiV4UiV8UsV8Us", "nc") +BUILTIN(__builtin_msa_dpsub_u_d, "V2ULLiV2ULLiV4UiV4Ui", "nc") + +BUILTIN(__builtin_msa_fadd_w, "V4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fadd_d, "V2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_fcaf_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fcaf_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fceq_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fceq_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fclass_w, "V4iV4f", "nc") +BUILTIN(__builtin_msa_fclass_d, "V2LLiV2d", "nc") + +BUILTIN(__builtin_msa_fcle_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fcle_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fclt_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fclt_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fcne_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fcne_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fcor_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fcor_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fcueq_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fcueq_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fcule_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fcule_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fcult_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fcult_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fcun_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fcun_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fcune_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fcune_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fdiv_w, "V4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fdiv_d, "V2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_fexdo_h, "V8hV4fV4f", "nc") +BUILTIN(__builtin_msa_fexdo_w, "V4fV2dV2d", "nc") + +BUILTIN(__builtin_msa_fexp2_w, "V4fV4fV4i", "nc") +BUILTIN(__builtin_msa_fexp2_d, "V2dV2dV2LLi", "nc") + +BUILTIN(__builtin_msa_fexupl_w, "V4fV8h", "nc") +BUILTIN(__builtin_msa_fexupl_d, "V2dV4f", "nc") + +BUILTIN(__builtin_msa_fexupr_w, "V4fV8h", "nc") +BUILTIN(__builtin_msa_fexupr_d, "V2dV4f", "nc") + +BUILTIN(__builtin_msa_ffint_s_w, "V4fV4Si", "nc") +BUILTIN(__builtin_msa_ffint_s_d, "V2dV2SLLi", "nc") + +BUILTIN(__builtin_msa_ffint_u_w, "V4fV4Ui", "nc") +BUILTIN(__builtin_msa_ffint_u_d, "V2dV2ULLi", "nc") + +// ffql uses integers since long _Fract is not implemented +BUILTIN(__builtin_msa_ffql_w, "V4fV8Ss", "nc") +BUILTIN(__builtin_msa_ffql_d, "V2dV4Si", "nc") + +// ffqr uses integers since long _Fract is not implemented +BUILTIN(__builtin_msa_ffqr_w, "V4fV8Ss", "nc") +BUILTIN(__builtin_msa_ffqr_d, "V2dV4Si", "nc") + +BUILTIN(__builtin_msa_fill_b, "V16Sci", "nc") +BUILTIN(__builtin_msa_fill_h, "V8Ssi", "nc") +BUILTIN(__builtin_msa_fill_w, "V4Sii", "nc") +BUILTIN(__builtin_msa_fill_d, "V2SLLiLLi", "nc") + +BUILTIN(__builtin_msa_flog2_w, "V4fV4f", "nc") +BUILTIN(__builtin_msa_flog2_d, "V2dV2d", "nc") + +BUILTIN(__builtin_msa_fmadd_w, "V4fV4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fmadd_d, "V2dV2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_fmax_w, "V4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fmax_d, "V2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_fmax_a_w, "V4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fmax_a_d, "V2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_fmin_w, "V4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fmin_d, "V2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_fmin_a_w, "V4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fmin_a_d, "V2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_fmsub_w, "V4fV4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fmsub_d, "V2dV2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_fmul_w, "V4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fmul_d, "V2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_frint_w, "V4fV4f", "nc") +BUILTIN(__builtin_msa_frint_d, "V2dV2d", "nc") + +BUILTIN(__builtin_msa_frcp_w, "V4fV4f", "nc") +BUILTIN(__builtin_msa_frcp_d, "V2dV2d", "nc") + +BUILTIN(__builtin_msa_frsqrt_w, "V4fV4f", "nc") +BUILTIN(__builtin_msa_frsqrt_d, "V2dV2d", "nc") + +BUILTIN(__builtin_msa_fsaf_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fsaf_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fseq_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fseq_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fsle_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fsle_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fslt_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fslt_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fsne_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fsne_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fsor_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fsor_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fsqrt_w, "V4fV4f", "nc") +BUILTIN(__builtin_msa_fsqrt_d, "V2dV2d", "nc") + +BUILTIN(__builtin_msa_fsub_w, "V4fV4fV4f", "nc") +BUILTIN(__builtin_msa_fsub_d, "V2dV2dV2d", "nc") + +BUILTIN(__builtin_msa_fsueq_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fsueq_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fsule_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fsule_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fsult_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fsult_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fsun_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fsun_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_fsune_w, "V4iV4fV4f", "nc") +BUILTIN(__builtin_msa_fsune_d, "V2LLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_ftint_s_w, "V4SiV4f", "nc") +BUILTIN(__builtin_msa_ftint_s_d, "V2SLLiV2d", "nc") + +BUILTIN(__builtin_msa_ftint_u_w, "V4UiV4f", "nc") +BUILTIN(__builtin_msa_ftint_u_d, "V2ULLiV2d", "nc") + +BUILTIN(__builtin_msa_ftq_h, "V4UiV4fV4f", "nc") +BUILTIN(__builtin_msa_ftq_w, "V2ULLiV2dV2d", "nc") + +BUILTIN(__builtin_msa_ftrunc_s_w, "V4SiV4f", "nc") +BUILTIN(__builtin_msa_ftrunc_s_d, "V2SLLiV2d", "nc") + +BUILTIN(__builtin_msa_ftrunc_u_w, "V4UiV4f", "nc") +BUILTIN(__builtin_msa_ftrunc_u_d, "V2ULLiV2d", "nc") + +BUILTIN(__builtin_msa_hadd_s_h, "V8SsV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_hadd_s_w, "V4SiV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_hadd_s_d, "V2SLLiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_hadd_u_h, "V8UsV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_hadd_u_w, "V4UiV8UsV8Us", "nc") +BUILTIN(__builtin_msa_hadd_u_d, "V2ULLiV4UiV4Ui", "nc") + +BUILTIN(__builtin_msa_hsub_s_h, "V8SsV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_hsub_s_w, "V4SiV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_hsub_s_d, "V2SLLiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_hsub_u_h, "V8UsV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_hsub_u_w, "V4UiV8UsV8Us", "nc") +BUILTIN(__builtin_msa_hsub_u_d, "V2ULLiV4UiV4Ui", "nc") + +BUILTIN(__builtin_msa_ilvev_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_ilvev_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_ilvev_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_ilvev_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_ilvl_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_ilvl_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_ilvl_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_ilvl_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_ilvod_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_ilvod_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_ilvod_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_ilvod_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_ilvr_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_ilvr_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_ilvr_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_ilvr_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_insert_b, "V16ScV16ScIUii", "nc") +BUILTIN(__builtin_msa_insert_h, "V8SsV8SsIUii", "nc") +BUILTIN(__builtin_msa_insert_w, "V4SiV4SiIUii", "nc") +BUILTIN(__builtin_msa_insert_d, "V2SLLiV2SLLiIUiLLi", "nc") + +BUILTIN(__builtin_msa_insve_b, "V16ScV16ScIUiV16Sc", "nc") +BUILTIN(__builtin_msa_insve_h, "V8SsV8SsIUiV8Ss", "nc") +BUILTIN(__builtin_msa_insve_w, "V4SiV4SiIUiV4Si", "nc") +BUILTIN(__builtin_msa_insve_d, "V2SLLiV2SLLiIUiV2SLLi", "nc") + +BUILTIN(__builtin_msa_ld_b, "V16Scv*Ii", "nc") +BUILTIN(__builtin_msa_ld_h, "V8Ssv*Ii", "nc") +BUILTIN(__builtin_msa_ld_w, "V4Siv*Ii", "nc") +BUILTIN(__builtin_msa_ld_d, "V2SLLiv*Ii", "nc") + +BUILTIN(__builtin_msa_ldi_b, "V16cIi", "nc") +BUILTIN(__builtin_msa_ldi_h, "V8sIi", "nc") +BUILTIN(__builtin_msa_ldi_w, "V4iIi", "nc") +BUILTIN(__builtin_msa_ldi_d, "V2LLiIi", "nc") + +BUILTIN(__builtin_msa_madd_q_h, "V8SsV8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_madd_q_w, "V4SiV4SiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_maddr_q_h, "V8SsV8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_maddr_q_w, "V4SiV4SiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_maddv_b, "V16ScV16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_maddv_h, "V8SsV8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_maddv_w, "V4SiV4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_maddv_d, "V2SLLiV2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_max_a_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_max_a_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_max_a_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_max_a_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_max_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_max_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_max_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_max_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_max_u_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_max_u_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_max_u_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_max_u_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_maxi_s_b, "V16ScV16ScIi", "nc") +BUILTIN(__builtin_msa_maxi_s_h, "V8SsV8SsIi", "nc") +BUILTIN(__builtin_msa_maxi_s_w, "V4SiV4SiIi", "nc") +BUILTIN(__builtin_msa_maxi_s_d, "V2SLLiV2SLLiIi", "nc") + +BUILTIN(__builtin_msa_maxi_u_b, "V16UcV16UcIi", "nc") +BUILTIN(__builtin_msa_maxi_u_h, "V8UsV8UsIi", "nc") +BUILTIN(__builtin_msa_maxi_u_w, "V4UiV4UiIi", "nc") +BUILTIN(__builtin_msa_maxi_u_d, "V2ULLiV2ULLiIi", "nc") + +BUILTIN(__builtin_msa_min_a_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_min_a_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_min_a_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_min_a_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_min_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_min_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_min_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_min_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_min_u_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_min_u_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_min_u_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_min_u_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_mini_s_b, "V16ScV16ScIi", "nc") +BUILTIN(__builtin_msa_mini_s_h, "V8SsV8SsIi", "nc") +BUILTIN(__builtin_msa_mini_s_w, "V4SiV4SiIi", "nc") +BUILTIN(__builtin_msa_mini_s_d, "V2SLLiV2SLLiIi", "nc") + +BUILTIN(__builtin_msa_mini_u_b, "V16UcV16UcIi", "nc") +BUILTIN(__builtin_msa_mini_u_h, "V8UsV8UsIi", "nc") +BUILTIN(__builtin_msa_mini_u_w, "V4UiV4UiIi", "nc") +BUILTIN(__builtin_msa_mini_u_d, "V2ULLiV2ULLiIi", "nc") + +BUILTIN(__builtin_msa_mod_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_mod_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_mod_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_mod_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_mod_u_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_mod_u_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_mod_u_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_mod_u_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_move_v, "V16ScV16Sc", "nc") + +BUILTIN(__builtin_msa_msub_q_h, "V8SsV8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_msub_q_w, "V4SiV4SiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_msubr_q_h, "V8SsV8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_msubr_q_w, "V4SiV4SiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_msubv_b, "V16ScV16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_msubv_h, "V8SsV8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_msubv_w, "V4SiV4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_msubv_d, "V2SLLiV2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_mul_q_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_mul_q_w, "V4SiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_mulr_q_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_mulr_q_w, "V4SiV4SiV4Si", "nc") + +BUILTIN(__builtin_msa_mulv_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_mulv_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_mulv_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_mulv_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_nloc_b, "V16ScV16Sc", "nc") +BUILTIN(__builtin_msa_nloc_h, "V8SsV8Ss", "nc") +BUILTIN(__builtin_msa_nloc_w, "V4SiV4Si", "nc") +BUILTIN(__builtin_msa_nloc_d, "V2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_nlzc_b, "V16ScV16Sc", "nc") +BUILTIN(__builtin_msa_nlzc_h, "V8SsV8Ss", "nc") +BUILTIN(__builtin_msa_nlzc_w, "V4SiV4Si", "nc") +BUILTIN(__builtin_msa_nlzc_d, "V2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_nor_v, "V16UcV16UcV16Uc", "nc") + +BUILTIN(__builtin_msa_nori_b, "V16UcV16cIUi", "nc") + +BUILTIN(__builtin_msa_or_v, "V16UcV16UcV16Uc", "nc") + +BUILTIN(__builtin_msa_ori_b, "V16UcV16UcIUi", "nc") + +BUILTIN(__builtin_msa_pckev_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_pckev_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_pckev_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_pckev_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_pckod_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_pckod_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_pckod_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_pckod_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_pcnt_b, "V16ScV16Sc", "nc") +BUILTIN(__builtin_msa_pcnt_h, "V8SsV8Ss", "nc") +BUILTIN(__builtin_msa_pcnt_w, "V4SiV4Si", "nc") +BUILTIN(__builtin_msa_pcnt_d, "V2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_sat_s_b, "V16ScV16ScIUi", "nc") +BUILTIN(__builtin_msa_sat_s_h, "V8SsV8SsIUi", "nc") +BUILTIN(__builtin_msa_sat_s_w, "V4SiV4SiIUi", "nc") +BUILTIN(__builtin_msa_sat_s_d, "V2SLLiV2SLLiIUi", "nc") + +BUILTIN(__builtin_msa_sat_u_b, "V16UcV16UcIUi", "nc") +BUILTIN(__builtin_msa_sat_u_h, "V8UsV8UsIUi", "nc") +BUILTIN(__builtin_msa_sat_u_w, "V4UiV4UiIUi", "nc") +BUILTIN(__builtin_msa_sat_u_d, "V2ULLiV2ULLiIUi", "nc") + +BUILTIN(__builtin_msa_shf_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_shf_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_shf_w, "V4iV4iIUi", "nc") + +BUILTIN(__builtin_msa_sld_b, "V16cV16cUi", "nc") +BUILTIN(__builtin_msa_sld_h, "V8sV8sUi", "nc") +BUILTIN(__builtin_msa_sld_w, "V4iV4iUi", "nc") +BUILTIN(__builtin_msa_sld_d, "V2LLiV2LLiUi", "nc") + +BUILTIN(__builtin_msa_sldi_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_sldi_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_sldi_w, "V4iV4iIUi", "nc") +BUILTIN(__builtin_msa_sldi_d, "V2LLiV2LLiIUi", "nc") + +BUILTIN(__builtin_msa_sll_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_sll_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_sll_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_sll_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_slli_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_slli_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_slli_w, "V4iV4iIUi", "nc") +BUILTIN(__builtin_msa_slli_d, "V2LLiV2LLiIUi", "nc") + +BUILTIN(__builtin_msa_splat_b, "V16cV16cUi", "nc") +BUILTIN(__builtin_msa_splat_h, "V8sV8sUi", "nc") +BUILTIN(__builtin_msa_splat_w, "V4iV4iUi", "nc") +BUILTIN(__builtin_msa_splat_d, "V2LLiV2LLiUi", "nc") + +BUILTIN(__builtin_msa_splati_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_splati_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_splati_w, "V4iV4iIUi", "nc") +BUILTIN(__builtin_msa_splati_d, "V2LLiV2LLiIUi", "nc") + +BUILTIN(__builtin_msa_sra_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_sra_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_sra_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_sra_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_srai_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_srai_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_srai_w, "V4iV4iIUi", "nc") +BUILTIN(__builtin_msa_srai_d, "V2LLiV2LLiIUi", "nc") + +BUILTIN(__builtin_msa_srar_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_srar_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_srar_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_srar_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_srari_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_srari_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_srari_w, "V4iV4iIUi", "nc") +BUILTIN(__builtin_msa_srari_d, "V2LLiV2LLiIUi", "nc") + +BUILTIN(__builtin_msa_srl_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_srl_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_srl_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_srl_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_srli_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_srli_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_srli_w, "V4iV4iIUi", "nc") +BUILTIN(__builtin_msa_srli_d, "V2LLiV2LLiIUi", "nc") + +BUILTIN(__builtin_msa_srlr_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_srlr_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_srlr_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_srlr_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_srlri_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_srlri_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_srlri_w, "V4iV4iIUi", "nc") +BUILTIN(__builtin_msa_srlri_d, "V2LLiV2LLiIUi", "nc") + +BUILTIN(__builtin_msa_st_b, "vV16Scv*Ii", "nc") +BUILTIN(__builtin_msa_st_h, "vV8Ssv*Ii", "nc") +BUILTIN(__builtin_msa_st_w, "vV4Siv*Ii", "nc") +BUILTIN(__builtin_msa_st_d, "vV2SLLiv*Ii", "nc") + +BUILTIN(__builtin_msa_subs_s_b, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_msa_subs_s_h, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_msa_subs_s_w, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_msa_subs_s_d, "V2SLLiV2SLLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_subs_u_b, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_subs_u_h, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_subs_u_w, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_subs_u_d, "V2ULLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_subsus_u_b, "V16UcV16UcV16Sc", "nc") +BUILTIN(__builtin_msa_subsus_u_h, "V8UsV8UsV8Ss", "nc") +BUILTIN(__builtin_msa_subsus_u_w, "V4UiV4UiV4Si", "nc") +BUILTIN(__builtin_msa_subsus_u_d, "V2ULLiV2ULLiV2SLLi", "nc") + +BUILTIN(__builtin_msa_subsuu_s_b, "V16ScV16UcV16Uc", "nc") +BUILTIN(__builtin_msa_subsuu_s_h, "V8SsV8UsV8Us", "nc") +BUILTIN(__builtin_msa_subsuu_s_w, "V4SiV4UiV4Ui", "nc") +BUILTIN(__builtin_msa_subsuu_s_d, "V2SLLiV2ULLiV2ULLi", "nc") + +BUILTIN(__builtin_msa_subv_b, "V16cV16cV16c", "nc") +BUILTIN(__builtin_msa_subv_h, "V8sV8sV8s", "nc") +BUILTIN(__builtin_msa_subv_w, "V4iV4iV4i", "nc") +BUILTIN(__builtin_msa_subv_d, "V2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_subvi_b, "V16cV16cIUi", "nc") +BUILTIN(__builtin_msa_subvi_h, "V8sV8sIUi", "nc") +BUILTIN(__builtin_msa_subvi_w, "V4iV4iIUi", "nc") +BUILTIN(__builtin_msa_subvi_d, "V2LLiV2LLiIUi", "nc") + +BUILTIN(__builtin_msa_vshf_b, "V16cV16cV16cV16c", "nc") +BUILTIN(__builtin_msa_vshf_h, "V8sV8sV8sV8s", "nc") +BUILTIN(__builtin_msa_vshf_w, "V4iV4iV4iV4i", "nc") +BUILTIN(__builtin_msa_vshf_d, "V2LLiV2LLiV2LLiV2LLi", "nc") + +BUILTIN(__builtin_msa_xor_v, "V16cV16cV16c", "nc") + +BUILTIN(__builtin_msa_xori_b, "V16cV16cIUi", "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 3c3f06c..7e9b5ee 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def @@ -61,248 +61,506 @@ 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") +// MISC + +BUILTIN(__nvvm_clz_i, "ii", "") +BUILTIN(__nvvm_clz_ll, "iLLi", "") +BUILTIN(__nvvm_popc_i, "ii", "") +BUILTIN(__nvvm_popc_ll, "iLLi", "") +BUILTIN(__nvvm_prmt, "UiUiUiUi", "") + +// Min Max + +BUILTIN(__nvvm_min_i, "iii", "") +BUILTIN(__nvvm_min_ui, "UiUiUi", "") +BUILTIN(__nvvm_min_ll, "LLiLLiLLi", "") +BUILTIN(__nvvm_min_ull, "ULLiULLiULLi", "") + +BUILTIN(__nvvm_max_i, "iii", "") +BUILTIN(__nvvm_max_ui, "UiUiUi", "") +BUILTIN(__nvvm_max_ll, "LLiLLiLLi", "") +BUILTIN(__nvvm_max_ull, "ULLiULLiULLi", "") + +BUILTIN(__nvvm_fmax_ftz_f, "fff", "") +BUILTIN(__nvvm_fmax_f, "fff", "") +BUILTIN(__nvvm_fmin_ftz_f, "fff", "") +BUILTIN(__nvvm_fmin_f, "fff", "") + +BUILTIN(__nvvm_fmax_d, "ddd", "") +BUILTIN(__nvvm_fmin_d, "ddd", "") + +// Multiplication + +BUILTIN(__nvvm_mulhi_i, "iii", "") +BUILTIN(__nvvm_mulhi_ui, "UiUiUi", "") +BUILTIN(__nvvm_mulhi_ll, "LLiLLiLLi", "") +BUILTIN(__nvvm_mulhi_ull, "ULLiULLiULLi", "") + +BUILTIN(__nvvm_mul_rn_ftz_f, "fff", "") +BUILTIN(__nvvm_mul_rn_f, "fff", "") +BUILTIN(__nvvm_mul_rz_ftz_f, "fff", "") +BUILTIN(__nvvm_mul_rz_f, "fff", "") +BUILTIN(__nvvm_mul_rm_ftz_f, "fff", "") +BUILTIN(__nvvm_mul_rm_f, "fff", "") +BUILTIN(__nvvm_mul_rp_ftz_f, "fff", "") +BUILTIN(__nvvm_mul_rp_f, "fff", "") + +BUILTIN(__nvvm_mul_rn_d, "ddd", "") +BUILTIN(__nvvm_mul_rz_d, "ddd", "") +BUILTIN(__nvvm_mul_rm_d, "ddd", "") +BUILTIN(__nvvm_mul_rp_d, "ddd", "") + +BUILTIN(__nvvm_mul24_i, "iii", "") +BUILTIN(__nvvm_mul24_ui, "UiUiUi", "") + +// Div + +BUILTIN(__nvvm_div_approx_ftz_f, "fff", "") +BUILTIN(__nvvm_div_approx_f, "fff", "") + +BUILTIN(__nvvm_div_rn_ftz_f, "fff", "") +BUILTIN(__nvvm_div_rn_f, "fff", "") +BUILTIN(__nvvm_div_rz_ftz_f, "fff", "") +BUILTIN(__nvvm_div_rz_f, "fff", "") +BUILTIN(__nvvm_div_rm_ftz_f, "fff", "") +BUILTIN(__nvvm_div_rm_f, "fff", "") +BUILTIN(__nvvm_div_rp_ftz_f, "fff", "") +BUILTIN(__nvvm_div_rp_f, "fff", "") + +BUILTIN(__nvvm_div_rn_d, "ddd", "") +BUILTIN(__nvvm_div_rz_d, "ddd", "") +BUILTIN(__nvvm_div_rm_d, "ddd", "") +BUILTIN(__nvvm_div_rp_d, "ddd", "") + +// Brev + +BUILTIN(__nvvm_brev32, "UiUi", "") +BUILTIN(__nvvm_brev64, "ULLiULLi", "") + +// Sad + +BUILTIN(__nvvm_sad_i, "iii", "") +BUILTIN(__nvvm_sad_ui, "UiUiUi", "") + +// Floor, Ceil + +BUILTIN(__nvvm_floor_ftz_f, "ff", "") +BUILTIN(__nvvm_floor_f, "ff", "") +BUILTIN(__nvvm_floor_d, "dd", "") + +BUILTIN(__nvvm_ceil_ftz_f, "ff", "") +BUILTIN(__nvvm_ceil_f, "ff", "") +BUILTIN(__nvvm_ceil_d, "dd", "") + +// Abs + +BUILTIN(__nvvm_abs_i, "ii", "") +BUILTIN(__nvvm_abs_ll, "LLiLLi", "") + +BUILTIN(__nvvm_fabs_ftz_f, "ff", "") +BUILTIN(__nvvm_fabs_f, "ff", "") +BUILTIN(__nvvm_fabs_d, "dd", "") + +// Round + +BUILTIN(__nvvm_round_ftz_f, "ff", "") +BUILTIN(__nvvm_round_f, "ff", "") +BUILTIN(__nvvm_round_d, "dd", "") + +// Trunc + +BUILTIN(__nvvm_trunc_ftz_f, "ff", "") +BUILTIN(__nvvm_trunc_f, "ff", "") +BUILTIN(__nvvm_trunc_d, "dd", "") + +// Saturate + +BUILTIN(__nvvm_saturate_ftz_f, "ff", "") +BUILTIN(__nvvm_saturate_f, "ff", "") +BUILTIN(__nvvm_saturate_d, "dd", "") + +// Exp2, Log2 + +BUILTIN(__nvvm_ex2_approx_ftz_f, "ff", "") +BUILTIN(__nvvm_ex2_approx_f, "ff", "") +BUILTIN(__nvvm_ex2_approx_d, "dd", "") + +BUILTIN(__nvvm_lg2_approx_ftz_f, "ff", "") +BUILTIN(__nvvm_lg2_approx_f, "ff", "") +BUILTIN(__nvvm_lg2_approx_d, "dd", "") + +// Sin, Cos + +BUILTIN(__nvvm_sin_approx_ftz_f, "ff", "") +BUILTIN(__nvvm_sin_approx_f, "ff", "") + +BUILTIN(__nvvm_cos_approx_ftz_f, "ff", "") +BUILTIN(__nvvm_cos_approx_f, "ff", "") + +// Fma + +BUILTIN(__nvvm_fma_rn_ftz_f, "ffff", "") +BUILTIN(__nvvm_fma_rn_f, "ffff", "") +BUILTIN(__nvvm_fma_rz_ftz_f, "ffff", "") +BUILTIN(__nvvm_fma_rz_f, "ffff", "") +BUILTIN(__nvvm_fma_rm_ftz_f, "ffff", "") +BUILTIN(__nvvm_fma_rm_f, "ffff", "") +BUILTIN(__nvvm_fma_rp_ftz_f, "ffff", "") +BUILTIN(__nvvm_fma_rp_f, "ffff", "") +BUILTIN(__nvvm_fma_rn_d, "dddd", "") +BUILTIN(__nvvm_fma_rz_d, "dddd", "") +BUILTIN(__nvvm_fma_rm_d, "dddd", "") +BUILTIN(__nvvm_fma_rp_d, "dddd", "") + +// Rcp + +BUILTIN(__nvvm_rcp_rn_ftz_f, "ff", "") +BUILTIN(__nvvm_rcp_rn_f, "ff", "") +BUILTIN(__nvvm_rcp_rz_ftz_f, "ff", "") +BUILTIN(__nvvm_rcp_rz_f, "ff", "") +BUILTIN(__nvvm_rcp_rm_ftz_f, "ff", "") +BUILTIN(__nvvm_rcp_rm_f, "ff", "") +BUILTIN(__nvvm_rcp_rp_ftz_f, "ff", "") +BUILTIN(__nvvm_rcp_rp_f, "ff", "") + +BUILTIN(__nvvm_rcp_rn_d, "dd", "") +BUILTIN(__nvvm_rcp_rz_d, "dd", "") +BUILTIN(__nvvm_rcp_rm_d, "dd", "") +BUILTIN(__nvvm_rcp_rp_d, "dd", "") +BUILTIN(__nvvm_rcp_approx_ftz_d, "dd", "") + +// Sqrt + +BUILTIN(__nvvm_sqrt_rn_ftz_f, "ff", "") +BUILTIN(__nvvm_sqrt_rn_f, "ff", "") +BUILTIN(__nvvm_sqrt_rz_ftz_f, "ff", "") +BUILTIN(__nvvm_sqrt_rz_f, "ff", "") +BUILTIN(__nvvm_sqrt_rm_ftz_f, "ff", "") +BUILTIN(__nvvm_sqrt_rm_f, "ff", "") +BUILTIN(__nvvm_sqrt_rp_ftz_f, "ff", "") +BUILTIN(__nvvm_sqrt_rp_f, "ff", "") +BUILTIN(__nvvm_sqrt_approx_ftz_f, "ff", "") +BUILTIN(__nvvm_sqrt_approx_f, "ff", "") + +BUILTIN(__nvvm_sqrt_rn_d, "dd", "") +BUILTIN(__nvvm_sqrt_rz_d, "dd", "") +BUILTIN(__nvvm_sqrt_rm_d, "dd", "") +BUILTIN(__nvvm_sqrt_rp_d, "dd", "") + +// Rsqrt + +BUILTIN(__nvvm_rsqrt_approx_ftz_f, "ff", "") +BUILTIN(__nvvm_rsqrt_approx_f, "ff", "") +BUILTIN(__nvvm_rsqrt_approx_d, "dd", "") + +// Add + +BUILTIN(__nvvm_add_rn_ftz_f, "ff", "") +BUILTIN(__nvvm_add_rn_f, "ff", "") +BUILTIN(__nvvm_add_rz_ftz_f, "ff", "") +BUILTIN(__nvvm_add_rz_f, "ff", "") +BUILTIN(__nvvm_add_rm_ftz_f, "ff", "") +BUILTIN(__nvvm_add_rm_f, "ff", "") +BUILTIN(__nvvm_add_rp_ftz_f, "ff", "") +BUILTIN(__nvvm_add_rp_f, "ff", "") + +BUILTIN(__nvvm_add_rn_d, "dd", "") +BUILTIN(__nvvm_add_rz_d, "dd", "") +BUILTIN(__nvvm_add_rm_d, "dd", "") +BUILTIN(__nvvm_add_rp_d, "dd", "") + +// Convert + +BUILTIN(__nvvm_d2f_rn_ftz, "fd", "") +BUILTIN(__nvvm_d2f_rn, "fd", "") +BUILTIN(__nvvm_d2f_rz_ftz, "fd", "") +BUILTIN(__nvvm_d2f_rz, "fd", "") +BUILTIN(__nvvm_d2f_rm_ftz, "fd", "") +BUILTIN(__nvvm_d2f_rm, "fd", "") +BUILTIN(__nvvm_d2f_rp_ftz, "fd", "") +BUILTIN(__nvvm_d2f_rp, "fd", "") + +BUILTIN(__nvvm_d2i_rn, "id", "") +BUILTIN(__nvvm_d2i_rz, "id", "") +BUILTIN(__nvvm_d2i_rm, "id", "") +BUILTIN(__nvvm_d2i_rp, "id", "") + +BUILTIN(__nvvm_d2ui_rn, "Uid", "") +BUILTIN(__nvvm_d2ui_rz, "Uid", "") +BUILTIN(__nvvm_d2ui_rm, "Uid", "") +BUILTIN(__nvvm_d2ui_rp, "Uid", "") + +BUILTIN(__nvvm_i2d_rn, "di", "") +BUILTIN(__nvvm_i2d_rz, "di", "") +BUILTIN(__nvvm_i2d_rm, "di", "") +BUILTIN(__nvvm_i2d_rp, "di", "") + +BUILTIN(__nvvm_ui2d_rn, "dUi", "") +BUILTIN(__nvvm_ui2d_rz, "dUi", "") +BUILTIN(__nvvm_ui2d_rm, "dUi", "") +BUILTIN(__nvvm_ui2d_rp, "dUi", "") + +BUILTIN(__nvvm_f2i_rn_ftz, "if", "") +BUILTIN(__nvvm_f2i_rn, "if", "") +BUILTIN(__nvvm_f2i_rz_ftz, "if", "") +BUILTIN(__nvvm_f2i_rz, "if", "") +BUILTIN(__nvvm_f2i_rm_ftz, "if", "") +BUILTIN(__nvvm_f2i_rm, "if", "") +BUILTIN(__nvvm_f2i_rp_ftz, "if", "") +BUILTIN(__nvvm_f2i_rp, "if", "") + +BUILTIN(__nvvm_f2ui_rn_ftz, "Uif", "") +BUILTIN(__nvvm_f2ui_rn, "Uif", "") +BUILTIN(__nvvm_f2ui_rz_ftz, "Uif", "") +BUILTIN(__nvvm_f2ui_rz, "Uif", "") +BUILTIN(__nvvm_f2ui_rm_ftz, "Uif", "") +BUILTIN(__nvvm_f2ui_rm, "Uif", "") +BUILTIN(__nvvm_f2ui_rp_ftz, "Uif", "") +BUILTIN(__nvvm_f2ui_rp, "Uif", "") + +BUILTIN(__nvvm_i2f_rn, "fi", "") +BUILTIN(__nvvm_i2f_rz, "fi", "") +BUILTIN(__nvvm_i2f_rm, "fi", "") +BUILTIN(__nvvm_i2f_rp, "fi", "") + +BUILTIN(__nvvm_ui2f_rn, "fUi", "") +BUILTIN(__nvvm_ui2f_rz, "fUi", "") +BUILTIN(__nvvm_ui2f_rm, "fUi", "") +BUILTIN(__nvvm_ui2f_rp, "fUi", "") + +BUILTIN(__nvvm_lohi_i2d, "dii", "") + +BUILTIN(__nvvm_d2i_lo, "id", "") +BUILTIN(__nvvm_d2i_hi, "id", "") + +BUILTIN(__nvvm_f2ll_rn_ftz, "LLif", "") +BUILTIN(__nvvm_f2ll_rn, "LLif", "") +BUILTIN(__nvvm_f2ll_rz_ftz, "LLif", "") +BUILTIN(__nvvm_f2ll_rz, "LLif", "") +BUILTIN(__nvvm_f2ll_rm_ftz, "LLif", "") +BUILTIN(__nvvm_f2ll_rm, "LLif", "") +BUILTIN(__nvvm_f2ll_rp_ftz, "LLif", "") +BUILTIN(__nvvm_f2ll_rp, "LLif", "") + +BUILTIN(__nvvm_f2ull_rn_ftz, "ULLif", "") +BUILTIN(__nvvm_f2ull_rn, "ULLif", "") +BUILTIN(__nvvm_f2ull_rz_ftz, "ULLif", "") +BUILTIN(__nvvm_f2ull_rz, "ULLif", "") +BUILTIN(__nvvm_f2ull_rm_ftz, "ULLif", "") +BUILTIN(__nvvm_f2ull_rm, "ULLif", "") +BUILTIN(__nvvm_f2ull_rp_ftz, "ULLif", "") +BUILTIN(__nvvm_f2ull_rp, "ULLif", "") + +BUILTIN(__nvvm_d2ll_rn, "LLid", "") +BUILTIN(__nvvm_d2ll_rz, "LLid", "") +BUILTIN(__nvvm_d2ll_rm, "LLid", "") +BUILTIN(__nvvm_d2ll_rp, "LLid", "") + +BUILTIN(__nvvm_d2ull_rn, "ULLid", "") +BUILTIN(__nvvm_d2ull_rz, "ULLid", "") +BUILTIN(__nvvm_d2ull_rm, "ULLid", "") +BUILTIN(__nvvm_d2ull_rp, "ULLid", "") + +BUILTIN(__nvvm_ll2f_rn, "fLLi", "") +BUILTIN(__nvvm_ll2f_rz, "fLLi", "") +BUILTIN(__nvvm_ll2f_rm, "fLLi", "") +BUILTIN(__nvvm_ll2f_rp, "fLLi", "") + +BUILTIN(__nvvm_ull2f_rn, "fULLi", "") +BUILTIN(__nvvm_ull2f_rz, "fULLi", "") +BUILTIN(__nvvm_ull2f_rm, "fULLi", "") +BUILTIN(__nvvm_ull2f_rp, "fULLi", "") + +BUILTIN(__nvvm_ll2d_rn, "dLLi", "") +BUILTIN(__nvvm_ll2d_rz, "dLLi", "") +BUILTIN(__nvvm_ll2d_rm, "dLLi", "") +BUILTIN(__nvvm_ll2d_rp, "dLLi", "") + +BUILTIN(__nvvm_ull2d_rn, "dULLi", "") +BUILTIN(__nvvm_ull2d_rz, "dULLi", "") +BUILTIN(__nvvm_ull2d_rm, "dULLi", "") +BUILTIN(__nvvm_ull2d_rp, "dULLi", "") + +BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "") +BUILTIN(__nvvm_f2h_rn, "Usf", "") + +BUILTIN(__nvvm_h2f, "fUs", "") + +// Bitcast + +BUILTIN(__nvvm_bitcast_f2i, "if", "") +BUILTIN(__nvvm_bitcast_i2f, "fi", "") + +BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "") +BUILTIN(__nvvm_bitcast_d2ll, "LLid", "") + +// Sync + +BUILTIN(__syncthreads, "v", "") +BUILTIN(__nvvm_bar0, "v", "") +BUILTIN(__nvvm_bar0_popc, "ii", "") +BUILTIN(__nvvm_bar0_and, "ii", "") +BUILTIN(__nvvm_bar0_or, "ii", "") + +// Membar + +BUILTIN(__nvvm_membar_cta, "v", "") +BUILTIN(__nvvm_membar_gl, "v", "") +BUILTIN(__nvvm_membar_sys, "v", "") + +// Memcpy, Memset + +BUILTIN(__nvvm_memcpy, "vUc*Uc*zi","") +BUILTIN(__nvvm_memset, "vUc*Uczi","") + +// Image + +BUILTIN(__builtin_ptx_read_image2Dfi_, "V4fiiii", "") +BUILTIN(__builtin_ptx_read_image2Dff_, "V4fiiff", "") +BUILTIN(__builtin_ptx_read_image2Dii_, "V4iiiii", "") +BUILTIN(__builtin_ptx_read_image2Dif_, "V4iiiff", "") + +BUILTIN(__builtin_ptx_read_image3Dfi_, "V4fiiiiii", "") +BUILTIN(__builtin_ptx_read_image3Dff_, "V4fiiffff", "") +BUILTIN(__builtin_ptx_read_image3Dii_, "V4iiiiiii", "") +BUILTIN(__builtin_ptx_read_image3Dif_, "V4iiiffff", "") + +BUILTIN(__builtin_ptx_write_image2Df_, "viiiffff", "") +BUILTIN(__builtin_ptx_write_image2Di_, "viiiiiii", "") +BUILTIN(__builtin_ptx_write_image2Dui_, "viiiUiUiUiUi", "") +BUILTIN(__builtin_ptx_get_image_depthi_, "ii", "") +BUILTIN(__builtin_ptx_get_image_heighti_, "ii", "") +BUILTIN(__builtin_ptx_get_image_widthi_, "ii", "") +BUILTIN(__builtin_ptx_get_image_channel_data_typei_, "ii", "") +BUILTIN(__builtin_ptx_get_image_channel_orderi_, "ii", "") + +// Atomic +// +// We need the atom intrinsics because +// - they are used in converging analysis +// - they are used in address space analysis and optimization +// So it does not hurt to expose them as builtins. +// +BUILTIN(__nvvm_atom_add_g_i, "iiD*1i", "n") +BUILTIN(__nvvm_atom_add_s_i, "iiD*3i", "n") +BUILTIN(__nvvm_atom_add_gen_i, "iiD*i", "n") +BUILTIN(__nvvm_atom_add_g_l, "LiLiD*1Li", "n") +BUILTIN(__nvvm_atom_add_s_l, "LiLiD*3Li", "n") +BUILTIN(__nvvm_atom_add_gen_l, "LiLiD*Li", "n") +BUILTIN(__nvvm_atom_add_g_ll, "LLiLLiD*1LLi", "n") +BUILTIN(__nvvm_atom_add_s_ll, "LLiLLiD*3LLi", "n") +BUILTIN(__nvvm_atom_add_gen_ll, "LLiLLiD*LLi", "n") +BUILTIN(__nvvm_atom_add_g_f, "ffD*1f", "n") +BUILTIN(__nvvm_atom_add_s_f, "ffD*3f", "n") +BUILTIN(__nvvm_atom_add_gen_f, "ffD*f", "n") + +BUILTIN(__nvvm_atom_sub_g_i, "iiD*1i", "n") +BUILTIN(__nvvm_atom_sub_s_i, "iiD*3i", "n") +BUILTIN(__nvvm_atom_sub_gen_i, "iiD*i", "n") +BUILTIN(__nvvm_atom_sub_g_l, "LiLiD*1Li", "n") +BUILTIN(__nvvm_atom_sub_s_l, "LiLiD*3Li", "n") +BUILTIN(__nvvm_atom_sub_gen_l, "LiLiD*Li", "n") +BUILTIN(__nvvm_atom_sub_g_ll, "LLiLLiD*1LLi", "n") +BUILTIN(__nvvm_atom_sub_s_ll, "LLiLLiD*3LLi", "n") +BUILTIN(__nvvm_atom_sub_gen_ll, "LLiLLiD*LLi", "n") + +BUILTIN(__nvvm_atom_xchg_g_i, "iiD*1i", "n") +BUILTIN(__nvvm_atom_xchg_s_i, "iiD*3i", "n") +BUILTIN(__nvvm_atom_xchg_gen_i, "iiD*i", "n") +BUILTIN(__nvvm_atom_xchg_g_l, "LiLiD*1Li", "n") +BUILTIN(__nvvm_atom_xchg_s_l, "LiLiD*3Li", "n") +BUILTIN(__nvvm_atom_xchg_gen_l, "LiLiD*Li", "n") +BUILTIN(__nvvm_atom_xchg_g_ll, "LLiLLiD*1LLi", "n") +BUILTIN(__nvvm_atom_xchg_s_ll, "LLiLLiD*3LLi", "n") +BUILTIN(__nvvm_atom_xchg_gen_ll, "LLiLLiD*LLi", "n") + +BUILTIN(__nvvm_atom_max_g_i, "iiD*1i", "n") +BUILTIN(__nvvm_atom_max_s_i, "iiD*3i", "n") +BUILTIN(__nvvm_atom_max_gen_i, "iiD*i", "n") +BUILTIN(__nvvm_atom_max_g_ui, "UiUiD*1Ui", "n") +BUILTIN(__nvvm_atom_max_s_ui, "UiUiD*3Ui", "n") +BUILTIN(__nvvm_atom_max_gen_ui, "UiUiD*Ui", "n") +BUILTIN(__nvvm_atom_max_g_l, "LiLiD*1Li", "n") +BUILTIN(__nvvm_atom_max_s_l, "LiLiD*3Li", "n") +BUILTIN(__nvvm_atom_max_gen_l, "LiLiD*Li", "n") +BUILTIN(__nvvm_atom_max_g_ul, "ULiULiD*1ULi", "n") +BUILTIN(__nvvm_atom_max_s_ul, "ULiULiD*3ULi", "n") +BUILTIN(__nvvm_atom_max_gen_ul, "ULiULiD*ULi", "n") +BUILTIN(__nvvm_atom_max_g_ll, "LLiLLiD*1LLi", "n") +BUILTIN(__nvvm_atom_max_s_ll, "LLiLLiD*3LLi", "n") +BUILTIN(__nvvm_atom_max_gen_ll, "LLiLLiD*LLi", "n") +BUILTIN(__nvvm_atom_max_g_ull, "ULLiULLiD*1ULLi", "n") +BUILTIN(__nvvm_atom_max_s_ull, "ULLiULLiD*3ULLi", "n") +BUILTIN(__nvvm_atom_max_gen_ull, "ULLiULLiD*ULLi", "n") + +BUILTIN(__nvvm_atom_min_g_i, "iiD*1i", "n") +BUILTIN(__nvvm_atom_min_s_i, "iiD*3i", "n") +BUILTIN(__nvvm_atom_min_gen_i, "iiD*i", "n") +BUILTIN(__nvvm_atom_min_g_ui, "UiUiD*1Ui", "n") +BUILTIN(__nvvm_atom_min_s_ui, "UiUiD*3Ui", "n") +BUILTIN(__nvvm_atom_min_gen_ui, "UiUiD*Ui", "n") +BUILTIN(__nvvm_atom_min_g_l, "LiLiD*1Li", "n") +BUILTIN(__nvvm_atom_min_s_l, "LiLiD*3Li", "n") +BUILTIN(__nvvm_atom_min_gen_l, "LiLi10D*Li", "n") +BUILTIN(__nvvm_atom_min_g_ul, "ULiULiD*1ULi", "n") +BUILTIN(__nvvm_atom_min_s_ul, "ULiULiD*3ULi", "n") +BUILTIN(__nvvm_atom_min_gen_ul, "ULiULiD*ULi", "n") +BUILTIN(__nvvm_atom_min_g_ll, "LLiLLiD*1LLi", "n") +BUILTIN(__nvvm_atom_min_s_ll, "LLiLLiD*3LLi", "n") +BUILTIN(__nvvm_atom_min_gen_ll, "LLiLLiD*LLi", "n") +BUILTIN(__nvvm_atom_min_g_ull, "ULLiULLiD*1ULLi", "n") +BUILTIN(__nvvm_atom_min_s_ull, "ULLiULLiD*3ULLi", "n") +BUILTIN(__nvvm_atom_min_gen_ull, "ULLiULLiD*ULLi", "n") + +BUILTIN(__nvvm_atom_inc_g_ui, "UiUiD*1Ui", "n") +BUILTIN(__nvvm_atom_inc_s_ui, "UiUiD*3Ui", "n") +BUILTIN(__nvvm_atom_inc_gen_ui, "UiUiD*Ui", "n") +BUILTIN(__nvvm_atom_dec_g_ui, "UiUiD*1Ui", "n") +BUILTIN(__nvvm_atom_dec_s_ui, "UiUiD*3Ui", "n") +BUILTIN(__nvvm_atom_dec_gen_ui, "UiUiD*Ui", "n") + +BUILTIN(__nvvm_atom_and_g_i, "iiD*1i", "n") +BUILTIN(__nvvm_atom_and_s_i, "iiD*3i", "n") +BUILTIN(__nvvm_atom_and_gen_i, "iiD*i", "n") +BUILTIN(__nvvm_atom_and_g_l, "LiLiD*1Li", "n") +BUILTIN(__nvvm_atom_and_s_l, "LiLiD*3Li", "n") +BUILTIN(__nvvm_atom_and_gen_l, "LiLiD*Li", "n") +BUILTIN(__nvvm_atom_and_g_ll, "LLiLLiD*1LLi", "n") +BUILTIN(__nvvm_atom_and_s_ll, "LLiLLiD*3LLi", "n") +BUILTIN(__nvvm_atom_and_gen_ll, "LLiLLiD*LLi", "n") + +BUILTIN(__nvvm_atom_or_g_i, "iiD*1i", "n") +BUILTIN(__nvvm_atom_or_s_i, "iiD*3i", "n") +BUILTIN(__nvvm_atom_or_gen_i, "iiD*i", "n") +BUILTIN(__nvvm_atom_or_g_l, "LiLiD*1Li", "n") +BUILTIN(__nvvm_atom_or_s_l, "LiLiD*3Li", "n") +BUILTIN(__nvvm_atom_or_gen_l, "LiLiD*Li", "n") +BUILTIN(__nvvm_atom_or_g_ll, "LLiLLiD*1LLi", "n") +BUILTIN(__nvvm_atom_or_s_ll, "LLiLLiD*3LLi", "n") +BUILTIN(__nvvm_atom_or_gen_ll, "LLiLLiD*LLi", "n") + +BUILTIN(__nvvm_atom_xor_g_i, "iiD*1i", "n") +BUILTIN(__nvvm_atom_xor_s_i, "iiD*3i", "n") +BUILTIN(__nvvm_atom_xor_gen_i, "iiD*i", "n") +BUILTIN(__nvvm_atom_xor_g_l, "LiLiD*1Li", "n") +BUILTIN(__nvvm_atom_xor_s_l, "LiLiD*3Li", "n") +BUILTIN(__nvvm_atom_xor_gen_l, "LiLiD*Li", "n") +BUILTIN(__nvvm_atom_xor_g_ll, "LLiLLiD*1LLi", "n") +BUILTIN(__nvvm_atom_xor_s_ll, "LLiLLiD*3LLi", "n") +BUILTIN(__nvvm_atom_xor_gen_ll, "LLiLLiD*LLi", "n") + +BUILTIN(__nvvm_atom_cas_g_i, "iiD*1ii", "n") +BUILTIN(__nvvm_atom_cas_s_i, "iiD*3ii", "n") +BUILTIN(__nvvm_atom_cas_gen_i, "iiD*ii", "n") +BUILTIN(__nvvm_atom_cas_g_l, "LiLiD*1LiLi", "n") +BUILTIN(__nvvm_atom_cas_s_l, "LiLiD*3LiLi", "n") +BUILTIN(__nvvm_atom_cas_gen_l, "LiLiD*LiLi", "n") +BUILTIN(__nvvm_atom_cas_g_ll, "LLiLLiD*1LLiLLi", "n") +BUILTIN(__nvvm_atom_cas_s_ll, "LLiLLiD*3LLiLLi", "n") +BUILTIN(__nvvm_atom_cas_gen_ll, "LLiLLiD*LLiLLi", "n") + +// Compiler Error Warn +BUILTIN(__nvvm_compiler_error, "vcC*4", "n") +BUILTIN(__nvvm_compiler_warn, "vcC*4", "n") #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 d536821..51397fa 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def @@ -258,6 +258,7 @@ BUILTIN(__builtin_ia32_storeupd, "vd*V2d", "") BUILTIN(__builtin_ia32_movmskpd, "iV2d", "") BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "") BUILTIN(__builtin_ia32_movnti, "vi*i", "") +BUILTIN(__builtin_ia32_movnti64, "vLLi*LLi", "") BUILTIN(__builtin_ia32_movntpd, "vd*V2d", "") BUILTIN(__builtin_ia32_movntdq, "vV2LLi*V2LLi", "") BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "") @@ -559,7 +560,7 @@ BUILTIN(__builtin_ia32_movntdqa256, "V4LLiV4LLi*", "") BUILTIN(__builtin_ia32_vbroadcastss_ps, "V4fV4f", "") BUILTIN(__builtin_ia32_vbroadcastss_ps256, "V8fV4f", "") BUILTIN(__builtin_ia32_vbroadcastsd_pd256, "V4dV2d", "") -BUILTIN(__builtin_ia32_vbroadcastsi256, "V4LLiV2LLiC*", "") +BUILTIN(__builtin_ia32_vbroadcastsi256, "V4LLiV2LLi", "") BUILTIN(__builtin_ia32_pblendd128, "V4iV4iV4iIi", "") BUILTIN(__builtin_ia32_pblendd256, "V8iV8iV8iIi", "") BUILTIN(__builtin_ia32_pbroadcastb256, "V32cV16c", "") @@ -641,6 +642,19 @@ BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "") BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "") BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "") +// TBM +BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "") +BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "") + +// SHA +BUILTIN(__builtin_ia32_sha1rnds4, "V4iV4iV4iIc", "") +BUILTIN(__builtin_ia32_sha1nexte, "V4iV4iV4i", "") +BUILTIN(__builtin_ia32_sha1msg1, "V4iV4iV4i", "") +BUILTIN(__builtin_ia32_sha1msg2, "V4iV4iV4i", "") +BUILTIN(__builtin_ia32_sha256rnds2, "V4iV4iV4iV4i", "") +BUILTIN(__builtin_ia32_sha256msg1, "V4iV4iV4i", "") +BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "") + // FMA4 BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "") BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "") diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsXCore.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsXCore.def new file mode 100644 index 0000000..672d205 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsXCore.def @@ -0,0 +1,22 @@ +//===--- BuiltinsXCore.def - XCore Builtin function database ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the XCore-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===----------------------------------------------------------------------===// + +// The format of this database matches clang/Basic/Builtins.def. + +BUILTIN(__builtin_bitrev, "UiUi", "nc") +BUILTIN(__builtin_getid, "Si", "nc") +BUILTIN(__builtin_getps, "UiUi", "n") +BUILTIN(__builtin_setps, "vUiUi", "n") + +#undef BUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/CapturedStmt.h b/contrib/llvm/tools/clang/include/clang/Basic/CapturedStmt.h index 484bbb1..c4a289b 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/CapturedStmt.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/CapturedStmt.h @@ -15,7 +15,8 @@ namespace clang { /// \brief The different kinds of captured statement. enum CapturedRegionKind { - CR_Default + CR_Default, + CR_OpenMP }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td b/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td index ad2afa7..18bca57 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td @@ -44,6 +44,9 @@ def Named : Decl<1>; def CXXDestructor : DDecl<CXXMethod>; def CXXConversion : DDecl<CXXMethod>; def Var : DDecl<Declarator>; + def VarTemplateSpecialization : DDecl<Var>; + def VarTemplatePartialSpecialization + : DDecl<VarTemplateSpecialization>; def ImplicitParam : DDecl<Var>; def ParmVar : DDecl<Var>; def NonTypeTemplateParm : DDecl<Declarator>; @@ -51,6 +54,7 @@ def Named : Decl<1>; def RedeclarableTemplate : DDecl<Template, 1>; def FunctionTemplate : DDecl<RedeclarableTemplate>; def ClassTemplate : DDecl<RedeclarableTemplate>; + def VarTemplate : DDecl<RedeclarableTemplate>; def TypeAliasTemplate : DDecl<RedeclarableTemplate>; def TemplateTemplateParm : DDecl<Template>; def Using : DDecl<Named>; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h index 3e12594..c057bdf 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h @@ -21,7 +21,6 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/Support/type_traits.h" #include <list> #include <vector> @@ -490,7 +489,14 @@ public: FatalErrorOccurred = true; LastDiagLevel = DiagnosticIDs::Ignored; } - + + /// \brief Determine whether the previous diagnostic was ignored. This can + /// be used by clients that want to determine whether notes attached to a + /// diagnostic will be suppressed. + bool isLastDiagnosticIgnored() const { + return LastDiagLevel == DiagnosticIDs::Ignored; + } + /// \brief Controls whether otherwise-unmapped extension diagnostics are /// mapped onto ignore/warning/error. /// @@ -983,6 +989,10 @@ public: bool hasMaxRanges() const { return NumRanges == DiagnosticsEngine::MaxRanges; } + + bool hasMaxFixItHints() const { + return NumFixits == DiagnosticsEngine::MaxFixItHints; + } }; inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, @@ -1212,7 +1222,7 @@ public: ~StoredDiagnostic(); /// \brief Evaluates true when this object stores a diagnostic. - operator bool() const { return Message.size() > 0; } + LLVM_EXPLICIT operator bool() const { return Message.size() > 0; } unsigned getID() const { return ID; } DiagnosticsEngine::Level getLevel() const { return Level; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td index 6dfecdc..2616548 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.td @@ -26,6 +26,13 @@ def CLASS_WARNING : DiagClass; def CLASS_EXTENSION : DiagClass; def CLASS_ERROR : DiagClass; +// Responses to a diagnostic in a SFINAE context. +class SFINAEResponse; +def SFINAE_SubstitutionFailure : SFINAEResponse; +def SFINAE_Suppress : SFINAEResponse; +def SFINAE_Report : SFINAEResponse; +def SFINAE_AccessControl : SFINAEResponse; + // Diagnostic Categories. These can be applied to groups or individual // diagnostics to specify a category. class DiagCategory<string Name> { @@ -52,19 +59,30 @@ include "DiagnosticGroups.td" // All diagnostics emitted by the compiler are an indirect subclass of this. class Diagnostic<string text, DiagClass DC, DiagMapping defaultmapping> { /// Component is specified by the file with a big let directive. - string Component = ?; - string Text = text; - DiagClass Class = DC; - bit SFINAE = 1; - bit AccessControl = 0; - bit WarningNoWerror = 0; - bit WarningShowInSystemHeader = 0; - DiagMapping DefaultMapping = defaultmapping; - DiagGroup Group; - string CategoryName = ""; + string Component = ?; + string Text = text; + DiagClass Class = DC; + SFINAEResponse SFINAE = SFINAE_Suppress; + bit AccessControl = 0; + bit WarningNoWerror = 0; + bit WarningShowInSystemHeader = 0; + DiagMapping DefaultMapping = defaultmapping; + DiagGroup Group; + string CategoryName = ""; +} + +class SFINAEFailure { + SFINAEResponse SFINAE = SFINAE_SubstitutionFailure; +} +class NoSFINAE { + SFINAEResponse SFINAE = SFINAE_Report; +} +class AccessControl { + SFINAEResponse SFINAE = SFINAE_AccessControl; } -class Error<string str> : Diagnostic<str, CLASS_ERROR, MAP_ERROR>; +// FIXME: ExtWarn and Extension should also be SFINAEFailure by default. +class Error<string str> : Diagnostic<str, CLASS_ERROR, MAP_ERROR>, SFINAEFailure; class Warning<string str> : Diagnostic<str, CLASS_WARNING, MAP_WARNING>; class Extension<string str> : Diagnostic<str, CLASS_EXTENSION, MAP_IGNORE>; class ExtWarn<string str> : Diagnostic<str, CLASS_EXTENSION, MAP_WARNING>; @@ -82,9 +100,6 @@ class DefaultWarnShowInSystemHeader { bit WarningShowInSystemHeader = 1; } -class NoSFINAE { bit SFINAE = 0; } -class AccessControl { bit AccessControl = 1; } - // Definitions for Diagnostics. include "DiagnosticASTKinds.td" include "DiagnosticAnalysisKinds.td" diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td index c69f85f..113e564 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -38,12 +38,16 @@ def note_constexpr_nonliteral : Note< def note_constexpr_non_global : Note< "%select{pointer|reference}0 to %select{|subobject of }1" "%select{temporary|%3}2 is not a constant expression">; +def note_constexpr_uninitialized : Note< + "%select{|sub}0object of type %1 is not initialized">; def note_constexpr_array_index : Note<"cannot refer to element %0 of " "%select{array of %2 elements|non-array object}1 in a constant expression">; def note_constexpr_float_arithmetic : Note< "floating point arithmetic produces %select{an infinity|a NaN}0">; def note_constexpr_pointer_subtraction_not_same_array : Note< "subtracted pointers are not elements of the same array">; +def note_constexpr_pointer_subtraction_zero_size : Note< + "subtraction of pointers to type %0 of zero size">; def note_constexpr_pointer_comparison_base_classes : Note< "comparison of addresses of subobjects of different base classes " "has unspecified value">; @@ -83,12 +87,17 @@ def note_constexpr_depth_limit_exceeded : Note< "constexpr evaluation exceeded maximum depth of %0 calls">; def note_constexpr_call_limit_exceeded : Note< "constexpr evaluation hit maximum call limit">; +def note_constexpr_step_limit_exceeded : Note< + "constexpr evaluation hit maximum step limit; possible infinite loop?">; def note_constexpr_lifetime_ended : Note< "%select{read of|assignment to|increment of|decrement of}0 " "%select{temporary|variable}1 whose lifetime has ended">; def note_constexpr_access_uninit : Note< "%select{read of|assignment to|increment of|decrement of}0 " "object outside its lifetime is not allowed in a constant expression">; +def note_constexpr_use_uninit_reference : Note< + "use of reference outside its lifetime " + "is not allowed in a constant expression">; def note_constexpr_modify_const_type : Note< "modification of object of const-qualified type %0 is not allowed " "in a constant expression">; @@ -115,9 +124,16 @@ def note_constexpr_access_inactive_union_member : Note< "%select{read of|assignment to|increment of|decrement of}0 " "member %1 of union with %select{active member %3|no active member}2 " "is not allowed in a constant expression">; +def note_constexpr_access_static_temporary : Note< + "%select{read of|assignment to|increment of|decrement of}0 temporary " + "is not allowed in a constant expression outside the expression that " + "created the temporary">; def note_constexpr_modify_global : Note< "a constant expression cannot modify an object that is visible outside " "that expression">; +def note_constexpr_stmt_expr_unsupported : Note< + "this use of statement expressions is not supported in a " + "constant expression">; def note_constexpr_calls_suppressed : Note< "(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to " "see all)">; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommentKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommentKinds.td index c913e31..49781fe 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommentKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommentKinds.td @@ -160,5 +160,9 @@ def warn_unknown_comment_command_name : Warning< "unknown command tag name">, InGroup<DocumentationUnknownCommand>, DefaultIgnore; +def warn_correct_comment_command_name : Warning< + "unknown command tag name '%0'; did you mean '%1'?">, + 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 7ff6ae1..c54bafc 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -37,6 +37,9 @@ def note_possibility : Note<"one possibility">; def note_also_found : Note<"also found">; // Parse && Lex + +let CategoryName = "Lexical or Preprocessor Issue" in { + def err_expected_colon : Error<"expected ':'">; def err_expected_colon_after_setter_name : Error< "method name referenced in property setter attribute " @@ -51,7 +54,12 @@ def err_invalid_character_udl : Error< def err_invalid_numeric_udl : Error< "numeric literal with user-defined suffix cannot be used here">; +} + // Parse && Sema + +let CategoryName = "Parse Issue" in { + def err_param_redefinition : Error<"redefinition of parameter %0">; def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">; def warn_method_param_declaration : Warning<"redeclaration of method parameter %0">, @@ -79,6 +87,8 @@ def err_attribute_not_type_attr : Error< "%0 attribute cannot be applied to types">; def err_enum_template : Error<"enumeration cannot be a template">; +} + // Sema && Lex def ext_c99_longlong : Extension< "'long long' is an extension when C99 mode is not enabled">, @@ -89,10 +99,10 @@ def ext_cxx11_longlong : Extension< def warn_cxx98_compat_longlong : Warning< "'long long' is incompatible with C++98">, InGroup<CXX98CompatPedantic>, DefaultIgnore; -def warn_integer_too_large : Warning< - "integer constant is too large for its type">; +def err_integer_too_large : Error< + "integer constant is larger than the largest unsigned integer type">; def warn_integer_too_large_for_signed : Warning< - "integer constant is so large that it is unsigned">; + "integer constant is larger than the largest signed integer type">; // Sema && AST def note_invalid_subexpr_in_const_expr : Note< @@ -105,7 +115,9 @@ def err_target_unknown_triple : Error< def err_target_unknown_cpu : Error<"unknown target CPU '%0'">; def err_target_unknown_abi : Error<"unknown target ABI '%0'">; def err_target_unknown_cxxabi : Error<"unknown C++ ABI '%0'">; -def err_target_invalid_feature : Error<"invalid target feature '%0'">; +def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">; +def err_target_unsupported_fpmath : Error< + "the '%0' unit is not supported with this instruction set">; // Source manager def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td index db457b1..b489807 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -26,8 +26,6 @@ def err_drv_unsupported_rtlib_for_platform : Error< "unsupported runtime library '%0' for platform '%1'">; def err_drv_invalid_stdlib_name : Error< "invalid library name in argument '%0'">; -def err_drv_invalid_opt_with_multiple_archs : Error< - "option '%0' cannot be used with multiple -arch options">; def err_drv_invalid_output_with_multiple_archs : Error< "cannot use '%0' output with multiple -arch options">; def err_drv_no_input_files : Error<"no input files">; @@ -35,8 +33,10 @@ def err_drv_use_of_Z_option : Error< "unsupported use of internal gcc -Z option '%0'">; def err_drv_output_argument_with_multiple_files : Error< "cannot specify -o when generating multiple output files">; -def err_no_external_windows_assembler : Error< - "there is no external assembler we can use on windows">; +def err_drv_out_file_argument_with_multiple_sources : Error< + "cannot specify '%0%1' when compiling multiple source files">; +def err_no_external_assembler : Error< + "there is no external assembler that can be used on this platform">; def err_drv_unable_to_remove_file : Error< "unable to remove file: %0">; def err_drv_command_failure : Error< @@ -77,8 +77,8 @@ def err_drv_invalid_mfloat_abi : Error< "invalid float ABI '%0'">; def err_drv_invalid_libcxx_deployment : Error< "invalid deployment target for -stdlib=libc++ (requires %0 or later)">; -def err_drv_invalid_feature : Error< - "invalid feature '%0' for CPU '%1'">; +def err_drv_malformed_sanitizer_blacklist : Error< + "malformed sanitizer blacklist: '%0'">; def err_drv_I_dash_not_supported : Error< "'%0' not supported, please use -iquote instead">; @@ -107,7 +107,14 @@ def err_drv_mg_requires_m_or_mm : Error< "option '-MG' requires '-M' or '-MM'">; def err_drv_unknown_objc_runtime : Error< "unknown or ill-formed Objective-C runtime '%0'">; +def err_drv_emit_llvm_link : Error< + "-emit-llvm cannot be used when linking">; +def err_drv_unknown_toolchain : Error< + "cannot recognize the type of the toolchain">; +def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>; +def warn_drv_optimization_value : Warning<"optimization level '%0' is unsupported; using '%1%2' instead">, + InGroup<InvalidCommandLineArgument>; def warn_c_kext : Warning< "ignoring -fapple-kext which is valid for C++ and Objective-C++ only">; def warn_drv_input_file_unused : Warning< @@ -135,6 +142,9 @@ def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; def warn_ignoring_ftabstop_value : Warning< "ignoring invalid -ftabstop value '%0', using default value %1">; +def warn_drv_overriding_flag_option : Warning< + "overriding '%0' option with '%1'">, + InGroup<DiagGroup<"overriding-t-option">>; def warn_drv_treating_input_as_cxx : Warning< "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">, InGroup<Deprecated>; @@ -147,6 +157,8 @@ def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">, def note_drv_command_failed_diag_msg : Note< "diagnostic msg: %0">; +def note_drv_t_option_is_global : + Note<"The last /TC or /TP option takes precedence over earlier instances">; def err_analyzer_config_no_value : Error< "analyzer-config option '%0' has a key but no value">; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td index f05fb9b..bcf3c41 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -11,7 +11,7 @@ let Component = "Frontend" in { def err_fe_error_opening : Error<"error opening '%0': %1">; def err_fe_error_reading : Error<"error reading '%0'">; -def err_fe_error_reading_stdin : Error<"error reading stdin">; +def err_fe_error_reading_stdin : Error<"error reading stdin: %0">; def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal; // Error generated by the backend. @@ -136,9 +136,8 @@ def err_no_submodule_suggest : Error< "no submodule named %0 in module '%1'; did you mean '%2'?">; def warn_missing_submodule : Warning<"missing submodule '%0'">, InGroup<IncompleteUmbrella>; -def err_module_map_temp_file : Error< - "unable to write temporary module map file '%0'">, DefaultFatal; -def err_module_unavailable : Error<"module '%0' requires feature '%1'">; +def err_module_unavailable : Error< + "module '%0' %select{is incompatible with|requires}1 feature '%2'">; def warn_module_config_macro_undef : Warning< "%select{definition|#undef}0 of configuration macro '%1' has no effect on " "the import of '%2'; pass '%select{-D%1=...|-U%1}0' on the command line " diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td index d5f777d..b0d0216 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td @@ -21,12 +21,16 @@ def : DiagGroup<"abi">; def : DiagGroup<"address">; def AddressOfTemporary : DiagGroup<"address-of-temporary">; def : DiagGroup<"aggregate-return">; +def GNUAlignofExpression : DiagGroup<"gnu-alignof-expression">; def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">; +def GNUAnonymousStruct : DiagGroup<"gnu-anonymous-struct">; def ArrayBounds : DiagGroup<"array-bounds">; def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">; def Availability : DiagGroup<"availability">; def Section : DiagGroup<"section">; def AutoImport : DiagGroup<"auto-import">; +def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">; +def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">; def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">; def ConstantConversion : DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >; @@ -45,23 +49,39 @@ def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">; def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">; def C99Compat : DiagGroup<"c99-compat">; def CXXCompat: DiagGroup<"c++-compat">; +def ExternCCompat : DiagGroup<"extern-c-compat">; +def KeywordCompat : DiagGroup<"keyword-compat">; +def GNUCaseRange : DiagGroup<"gnu-case-range">; def CastAlign : DiagGroup<"cast-align">; def : DiagGroup<"cast-qual">; def : DiagGroup<"char-align">; def Comment : DiagGroup<"comment">; +def GNUComplexInteger : DiagGroup<"gnu-complex-integer">; +def GNUConditionalOmittedOperand : DiagGroup<"gnu-conditional-omitted-operand">; def ConfigMacros : DiagGroup<"config-macros">; def : DiagGroup<"ctor-dtor-privacy">; def GNUDesignator : DiagGroup<"gnu-designator">; +def GNUStringLiteralOperatorTemplate : + DiagGroup<"gnu-string-literal-operator-template">; def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">; def AbstractFinalClass : DiagGroup<"abstract-final-class">; -def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; -def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings">; -def Deprecated : DiagGroup<"deprecated", [ DeprecatedDeclarations] >, - DiagCategory<"Deprecations">; +def CXX11CompatDeprecatedWritableStr : + DiagGroup<"c++11-compat-deprecated-writable-strings">; +def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; def DeprecatedImplementations :DiagGroup<"deprecated-implementations">; +def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">; +def DeprecatedRegister : DiagGroup<"deprecated-register">; +def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings", + [CXX11CompatDeprecatedWritableStr]>; +// FIXME: Why are DeprecatedImplementations and DeprecatedWritableStr +// not in this group? +def Deprecated : DiagGroup<"deprecated", [DeprecatedDeclarations, + DeprecatedIncrementBool, + DeprecatedRegister]>, + DiagCategory<"Deprecations">; def : DiagGroup<"disabled-optimization">; def : DiagGroup<"discard-qual">; @@ -77,16 +97,21 @@ def Documentation : DiagGroup<"documentation", DocumentationDeprecatedSync]>; def EmptyBody : DiagGroup<"empty-body">; +def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">; +def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">; def ExtraTokens : DiagGroup<"extra-tokens">; def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">; def ExtraSemi : DiagGroup<"extra-semi", [CXX11ExtraSemi]>; +def GNUFlexibleArrayInitializer : DiagGroup<"gnu-flexible-array-initializer">; +def GNUFlexibleArrayUnionMember : DiagGroup<"gnu-flexible-array-union-member">; +def GNUFoldingConstant : DiagGroup<"gnu-folding-constant">; def FormatExtraArgs : DiagGroup<"format-extra-args">; def FormatZeroLength : DiagGroup<"format-zero-length">; // Warnings for C++1y code which is not compatible with prior C++ standards. -def CXXPre1yCompat : DiagGroup<"cxx98-cxx11-compat">; -def CXXPre1yCompatPedantic : DiagGroup<"cxx98-cxx11-compat-pedantic", +def CXXPre1yCompat : DiagGroup<"c++98-c++11-compat">; +def CXXPre1yCompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic", [CXXPre1yCompat]>; def CXX98CompatBindToTemporaryCopy : @@ -123,6 +148,7 @@ def ReservedUserDefinedLiteral : def CXX11Compat : DiagGroup<"c++11-compat", [CXX11Narrowing, CXX11CompatReservedUserDefinedLiteral, + CXX11CompatDeprecatedWritableStr, CXXPre1yCompat]>; def : DiagGroup<"c++0x-compat", [CXX11Compat]>; def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic", @@ -136,11 +162,13 @@ def FourByteMultiChar : DiagGroup<"four-char-constants">; def GlobalConstructors : DiagGroup<"global-constructors">; def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">; def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">; +def LogicalNotParentheses: DiagGroup<"logical-not-parentheses">; def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">; def OverloadedShiftOpParentheses: DiagGroup<"overloaded-shift-op-parentheses">; def DanglingElse: DiagGroup<"dangling-else">; def DanglingField : DiagGroup<"dangling-field">; def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">; +def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">; def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">; def : DiagGroup<"import">; def IncompatiblePointerTypesDiscardsQualifiers @@ -149,15 +177,18 @@ def IncompatiblePointerTypes : DiagGroup<"incompatible-pointer-types", [IncompatiblePointerTypesDiscardsQualifiers]>; def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">; +def IncompleteModule : DiagGroup<"incomplete-module", [IncompleteUmbrella]>; def InvalidNoreturn : DiagGroup<"invalid-noreturn">; def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">; def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">; def : DiagGroup<"init-self">; def : DiagGroup<"inline">; def : DiagGroup<"invalid-pch">; +def GNULabelsAsValue : DiagGroup<"gnu-label-as-value">; def LiteralRange : DiagGroup<"literal-range">; def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args", [CXX98CompatLocalTypeTemplateArgs]>; +def LoopAnalysis : DiagGroup<"loop-analysis">; def MalformedWarningCheck : DiagGroup<"malformed-warning-check">; def Main : DiagGroup<"main">; def MainReturnType : DiagGroup<"main-return-type">; @@ -176,6 +207,7 @@ def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">; def MismatchedTags : DiagGroup<"mismatched-tags">; def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; def ModuleConflict : DiagGroup<"module-conflict">; +def NewlineEOF : DiagGroup<"newline-eof">; def NullArithmetic : DiagGroup<"null-arithmetic">; def NullCharacter : DiagGroup<"null-character">; def NullDereference : DiagGroup<"null-dereference">; @@ -202,7 +234,10 @@ def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">; def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">; def ObjCRetainBlockProperty : DiagGroup<"objc-noncopy-retain-block-property">; def ObjCReadonlyPropertyHasSetter : DiagGroup<"objc-readonly-with-setter-property">; +def ObjCInvalidIBOutletProperty : DiagGroup<"invalid-iboutlet">; def ObjCRootClass : DiagGroup<"objc-root-class">; +def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-introspection-performSelector">; +def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>; def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">; def Packed : DiagGroup<"packed">; def Padded : DiagGroup<"padded">; @@ -213,6 +248,8 @@ def PoundPragmaMessage : DiagGroup<"#pragma-messages">, DiagCategory<"#pragma message Directive">; def : DiagGroup<"pointer-to-int-cast">; def : DiagGroup<"redundant-decls">; +def RedeclaredClassMember : DiagGroup<"redeclared-class-member">; +def GNURedeclaredEnum : DiagGroup<"gnu-redeclared-enum">; def ReturnStackAddress : DiagGroup<"return-stack-address">; def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">; def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>; @@ -237,7 +274,9 @@ def StaticInInline : DiagGroup<"static-in-inline">; def StaticLocalInInline : DiagGroup<"static-local-in-inline">; def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">; def StaticFloatInit : DiagGroup<"static-float-init", [GNUStaticFloatInit]>; +def GNUStatementExpression : DiagGroup<"gnu-statement-expression">; def StringPlusInt : DiagGroup<"string-plus-int">; +def StringPlusChar : DiagGroup<"string-plus-char">; def StrncatSize : DiagGroup<"strncat-size">; def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">; def TautologicalCompare : DiagGroup<"tautological-compare", @@ -245,6 +284,9 @@ def TautologicalCompare : DiagGroup<"tautological-compare", def HeaderHygiene : DiagGroup<"header-hygiene">; def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">; def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">; +def GNUUnionCast : DiagGroup<"gnu-union-cast">; +def GNUVariableSizedTypeNotAtEnd : DiagGroup<"gnu-variable-sized-type-not-at-end">; +def Varargs : DiagGroup<"varargs">; def Unsequenced : DiagGroup<"unsequenced">; // GCC name for -Wunsequenced @@ -298,10 +340,12 @@ def UnknownAttributes : DiagGroup<"attributes">; def IgnoredAttributes : DiagGroup<"ignored-attributes">; def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args", [CXX98CompatUnnamedTypeTemplateArgs]>; +def UnsupportedFriend : DiagGroup<"unsupported-friend">; def UnusedArgument : DiagGroup<"unused-argument">; def UnusedSanitizeArgument : DiagGroup<"unused-sanitize-argument">; def UnusedCommandLineArgument : DiagGroup<"unused-command-line-argument", [UnusedSanitizeArgument]>; +def InvalidCommandLineArgument : DiagGroup<"invalid-command-line-argument">; def UnusedComparison : DiagGroup<"unused-comparison">; def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">; def UnneededInternalDecl : DiagGroup<"unneeded-internal-declaration">; @@ -314,7 +358,10 @@ def UnusedLabel : DiagGroup<"unused-label">; def UnusedParameter : DiagGroup<"unused-parameter">; def UnusedResult : DiagGroup<"unused-result">; def UnusedValue : DiagGroup<"unused-value", [UnusedComparison, UnusedResult]>; -def UnusedVariable : DiagGroup<"unused-variable">; +def UnusedConstVariable : DiagGroup<"unused-const-variable">; +def UnusedVariable : DiagGroup<"unused-variable", + [UnusedConstVariable]>; +def UnusedPropertyIvar : DiagGroup<"unused-property-ivar">; def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">; def UserDefinedLiterals : DiagGroup<"user-defined-literals">; def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">; @@ -336,7 +383,10 @@ def AutomaticReferenceCounting : DiagGroup<"arc", def ARCRepeatedUseOfWeakMaybe : DiagGroup<"arc-maybe-repeated-use-of-weak">; def ARCRepeatedUseOfWeak : DiagGroup<"arc-repeated-use-of-weak", [ARCRepeatedUseOfWeakMaybe]>; -def Selector : DiagGroup<"selector">; +def ObjCBridge : DiagGroup<"bridge-cast">; + +def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">; +def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>; def Protocol : DiagGroup<"protocol">; def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">; def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">; @@ -348,6 +398,8 @@ def VLAExtension : DiagGroup<"vla-extension">; def VolatileRegisterVar : DiagGroup<"volatile-register-var">; def Visibility : DiagGroup<"visibility">; def ZeroLengthArray : DiagGroup<"zero-length-array">; +def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">; +def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">; // GCC calls -Wdeprecated-writable-strings -Wwrite-strings. def GCCWriteStrings : DiagGroup<"write-strings" , [DeprecatedWritableStr]>; @@ -365,6 +417,7 @@ def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">; def ParenthesesOnEquality : DiagGroup<"parentheses-equality">; def Parentheses : DiagGroup<"parentheses", [LogicalOpParentheses, + LogicalNotParentheses, BitwiseOpParentheses, ShiftOpParentheses, OverloadedShiftOpParentheses, @@ -396,7 +449,7 @@ def Unused : DiagGroup<"unused", // UnusedParameter, (matches GCC's behavior) // UnusedMemberFunction, (clean-up llvm before enabling) UnusedPrivateField, - UnusedValue, UnusedVariable]>, + UnusedValue, UnusedVariable, UnusedPropertyIvar]>, DiagCategory<"Unused Entity Issue">; // Format settings. @@ -414,7 +467,9 @@ def Format2 : DiagGroup<"format=2", def TypeSafety : DiagGroup<"type-safety">; -def IntToPointerCast : DiagGroup<"int-to-pointer-cast">; +def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">; +def IntToPointerCast : DiagGroup<"int-to-pointer-cast", + [IntToVoidPointerCast]>; def Extra : DiagGroup<"extra", [ MissingFieldInitializers, @@ -449,7 +504,8 @@ def Most : DiagGroup<"most", [ ObjCMissingSuperCalls, OverloadedVirtual, PrivateExtern, - SelTypeCast + SelTypeCast, + ExternCCompat ]>; // Thread Safety warnings @@ -462,6 +518,9 @@ def ThreadSafety : DiagGroup<"thread-safety", ThreadSafetyPrecise]>; def ThreadSafetyBeta : DiagGroup<"thread-safety-beta">; +// Uniqueness Analysis warnings +def Consumed : DiagGroup<"consumed">; + // Note that putting warnings in -Wall will not disable them by default. If a // warning should be active _only_ when -Wall is passed in, mark it as // DefaultIgnore in addition to putting it here. @@ -472,7 +531,7 @@ def Pedantic : DiagGroup<"pedantic">; // Aliases. def : DiagGroup<"", [Extra]>; // -W = -Wextra -def : DiagGroup<"endif-labels", [ExtraTokens]>; // -Wendif-labels=-Wendif-tokens +def : DiagGroup<"endif-labels", [ExtraTokens]>; // -Wendif-labels=-Wextra-tokens def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment def : DiagGroup<"conversion-null", [NullConversion]>; // -Wconversion-null = -Wnull-conversion @@ -507,8 +566,20 @@ def C11 : DiagGroup<"c11-extensions">; def C99 : DiagGroup<"c99-extensions">; // A warning group for warnings about GCC extensions. -def GNU : DiagGroup<"gnu", [GNUDesignator, VLAExtension, - ZeroLengthArray, GNUStaticFloatInit]>; +def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct, + GNUBinaryLiteral, GNUCaseRange, + GNUComplexInteger, GNUCompoundLiteralInitializer, + GNUConditionalOmittedOperand, GNUDesignator, + GNUEmptyInitializer, GNUEmptyStruct, + VLAExtension, GNUFlexibleArrayInitializer, + GNUFlexibleArrayUnionMember, GNUFoldingConstant, + GNUImaginaryConstant, GNULabelsAsValue, + RedeclaredClassMember, GNURedeclaredEnum, + GNUStatementExpression, GNUStaticFloatInit, + GNUStringLiteralOperatorTemplate, + GNUUnionCast, GNUVariableSizedTypeNotAtEnd, + ZeroLengthArray, GNUZeroLineDirective, + GNUZeroVariadicMacroArguments]>; // A warning group for warnings about code that clang accepts but gcc doesn't. def GccCompat : DiagGroup<"gcc-compat">; @@ -532,10 +603,13 @@ def ObjCCocoaAPI : DiagGroup<"objc-cocoa-api", [ ]>; def ObjCStringComparison : DiagGroup<"objc-string-compare">; +def ObjCStringConcatenation : DiagGroup<"objc-string-concatenation">; def ObjCLiteralComparison : DiagGroup<"objc-literal-compare", [ ObjCStringComparison ]>; +def ObjCLiteralMissingAtSign : DiagGroup<"objc-literal-missing-atsign">; + // Inline ASM warnings. def ASMOperandWidths : DiagGroup<"asm-operand-widths">; def ASM : DiagGroup<"asm", [ diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h index d35b907..56e30fb 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticIDs.h @@ -22,13 +22,13 @@ namespace clang { class DiagnosticsEngine; class SourceLocation; - struct WarningOption; // Import the diagnostic enums themselves. namespace diag { // Start position for diagnostics. enum { - DIAG_START_DRIVER = 300, + DIAG_START_COMMON = 0, + DIAG_START_DRIVER = DIAG_START_COMMON + 300, DIAG_START_FRONTEND = DIAG_START_DRIVER + 100, DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100, DIAG_START_LEX = DIAG_START_SERIALIZATION + 120, @@ -48,7 +48,8 @@ namespace clang { // Get typedefs for common diagnostics. enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM, + SFINAE,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM, +#define COMMONSTART #include "clang/Basic/DiagnosticCommonKinds.inc" NUM_BUILTIN_COMMON_DIAGNOSTICS #undef DIAG @@ -105,11 +106,12 @@ public: void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } }; -/// \brief Used for handling and querying diagnostic IDs. Can be used and shared -/// by multiple Diagnostics for multiple translation units. +/// \brief Used for handling and querying diagnostic IDs. +/// +/// Can be used and shared by multiple Diagnostics for multiple translation units. class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> { public: - /// Level The level of the diagnostic, after it has been through mapping. + /// \brief The level of the diagnostic, after it has been through mapping. enum Level { Ignored, Note, Warning, Error, Fatal }; @@ -224,8 +226,8 @@ public: /// \brief Get the set of all diagnostic IDs in the group with the given name. /// - /// \param Diags [out] - On return, the diagnostics in the group. - /// \returns True if the given group is unknown, false otherwise. + /// \param[out] Diags - On return, the diagnostics in the group. + /// \returns \c true if the given group is unknown, \c false otherwise. bool getDiagnosticsInGroup(StringRef Group, SmallVectorImpl<diag::kind> &Diags) const; @@ -237,18 +239,14 @@ public: static StringRef getNearestWarningOption(StringRef Group); private: - /// \brief Get the set of all diagnostic IDs in the given group. - /// - /// \param Diags [out] - On return, the diagnostics in the group. - void getDiagnosticsInGroup(const WarningOption *Group, - SmallVectorImpl<diag::kind> &Diags) const; - - /// \brief Based on the way the client configured the DiagnosticsEngine - /// object, classify the specified diagnostic ID into a Level, consumable by + /// \brief Classify the specified diagnostic ID into a Level, consumable by /// the DiagnosticClient. + /// + /// The classification is based on the way the client configured the + /// DiagnosticsEngine object. /// - /// \param Loc The source location we are interested in finding out the - /// diagnostic state. Can be null in order to query the latest state. + /// \param Loc The source location for which we are interested in finding out + /// the diagnostic state. Can be null in order to query the latest state. DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, const DiagnosticsEngine &Diag) const; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td index 2c16000..871f5f6 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -47,7 +47,9 @@ 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">, - InGroup<DiagGroup<"newline-eof">>; + InGroup<NewlineEOF>; +def warn_no_newline_eof : Warning<"no newline at end of file">, + InGroup<NewlineEOF>, DefaultIgnore; def warn_cxx98_compat_no_newline_eof : Warning< "C++98 requires newline at end of file">, @@ -157,6 +159,11 @@ def err_invalid_suffix_integer_constant : Error< "invalid suffix '%0' on integer constant">; def err_invalid_suffix_float_constant : Error< "invalid suffix '%0' on floating constant">; +def warn_cxx11_compat_digit_separator : Warning< + "digit separators are incompatible with C++ standards before C++1y">, + InGroup<CXXPre1yCompat>, DefaultIgnore; +def err_digit_separator_not_between_digits : Error< + "digit separator cannot appear at %select{start|end}0 of digit sequence">; def warn_extraneous_char_constant : Warning< "extraneous characters in character constant ignored">; def warn_char_constant_too_large : Warning< @@ -165,7 +172,7 @@ 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 a GNU extension">, InGroup<GNU>; + "imaginary constants are a GNU extension">, InGroup<GNUImaginaryConstant>; def err_hexconstant_requires_exponent : Error< "hexadecimal floating constants require an exponent">; def err_hexconstant_requires_digits : Error< @@ -173,15 +180,15 @@ def err_hexconstant_requires_digits : Error< def ext_hexconstant_invalid : Extension< "hexadecimal floating constants are a C99 feature">, InGroup<C99>; def ext_binary_literal : Extension< - "binary integer literals are a GNU extension">, InGroup<GNU>; + "binary integer literals are a GNU extension">, InGroup<GNUBinaryLiteral>; def ext_binary_literal_cxx1y : Extension< "binary integer literals are a C++1y extension">, InGroup<CXX1y>; def warn_cxx11_compat_binary_literal : Warning< "binary integer literals are incompatible with C++ standards before C++1y">, InGroup<CXXPre1yCompatPedantic>, DefaultIgnore; 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">; +def err_octal_escape_too_large : Error<"octal escape sequence out of range">; +def err_hex_escape_too_large : Error<"hex escape sequence out of range">; def ext_string_too_long : Extension<"string literal of length %0 exceeds " "maximum length %1 that %select{C90|ISO C99|C++}2 compilers are required to " "support">, InGroup<OverlengthStrings>; @@ -320,7 +327,7 @@ def ext_embedded_directive : Extension< InGroup<DiagGroup<"embedded-directive">>; def ext_missing_varargs_arg : Extension< "must specify at least one argument for '...' parameter of variadic macro">, - InGroup<GNU>; + InGroup<GNUZeroVariadicMacroArguments>; def ext_empty_fnmacro_arg : Extension< "empty macro arguments are a C99 feature">, InGroup<C99>; def warn_cxx98_compat_empty_fnmacro_arg : Warning< @@ -406,6 +413,21 @@ def warn_pragma_include_alias_expected_filename : ExtWarn<"pragma include_alias expected include filename">, InGroup<UnknownPragmas>; +// - #pragma warning(...) +def warn_pragma_warning_expected : + ExtWarn<"#pragma warning expected '%0'">, + InGroup<UnknownPragmas>; +def warn_pragma_warning_spec_invalid : + ExtWarn<"#pragma warning expected 'push', 'pop', 'default', 'disable'," + " 'error', 'once', 'suppress', 1, 2, 3, or 4">, + InGroup<UnknownPragmas>; +def warn_pragma_warning_push_level : + ExtWarn<"#pragma warning(push, level) requires a level between 0 and 4">, + InGroup<UnknownPragmas>; +def warn_pragma_warning_expected_number : + ExtWarn<"#pragma warning expected a warning number">, + InGroup<UnknownPragmas>; + def err__Pragma_malformed : Error< "_Pragma takes a parenthesized string literal">; def err_pragma_message_malformed : Error< @@ -455,11 +477,16 @@ def err_paste_at_start : Error< "'##' cannot appear at start of macro expansion">; def err_paste_at_end : Error<"'##' cannot appear at end of macro expansion">; def ext_paste_comma : Extension< - "token pasting of ',' and __VA_ARGS__ is a GNU extension">, InGroup<GNU>; + "token pasting of ',' and __VA_ARGS__ is a GNU extension">, InGroup<GNUZeroVariadicMacroArguments>; def err_unterm_macro_invoc : Error< "unterminated function-like macro invocation">; def err_too_many_args_in_macro_invoc : Error< "too many arguments provided to function-like macro invocation">; +def note_suggest_parens_for_macro : Note< + "parentheses are required around macro argument containing braced " + "initializer list">; +def note_init_list_at_beginning_of_macro_argument : Note< + "cannot use initializer list at the beginning of a macro argument">; def err_too_few_args_in_macro_invoc : Error< "too few arguments provided to function-like macro invocation">; def err_pp_bad_paste : Error< @@ -475,7 +502,7 @@ def err_pp_line_requires_integer : Error< "#line directive requires a positive integer argument">; def ext_pp_line_zero : Extension< "#line directive with zero argument is a GNU extension">, - InGroup<GNU>; + InGroup<GNUZeroLineDirective>; def err_pp_line_invalid_filename : Error< "invalid filename for #line directive">; def warn_pp_line_decimal : Warning< @@ -520,19 +547,18 @@ def note_mmap_lsquare_match : Note<"to match this ']'">; def err_mmap_expected_member : Error< "expected umbrella, header, submodule, or module export">; def err_mmap_expected_header : Error<"expected a header name after '%0'">; +def err_mmap_expected_mmap_file : Error<"expected a module map file name">; def err_mmap_module_redefinition : Error< "redefinition of module '%0'">; def note_mmap_prev_definition : Note<"previously defined here">; -def err_mmap_header_conflict : Error< - "header '%0' is already part of module '%1'">; def err_mmap_header_not_found : Error< "%select{|umbrella }0header '%1' not found">; def err_mmap_umbrella_dir_not_found : Error< "umbrella directory '%0' not found">; def err_mmap_umbrella_clash : Error< "umbrella for module '%0' already covers this directory">; -def err_mmap_export_module_id : Error< - "expected an exported module name or '*'">; +def err_mmap_module_id : Error< + "expected a module name or '*'">; def err_mmap_expected_library_name : Error< "expected %select{library|framework}0 name as a string">; def err_mmap_config_macro_submodule : Error< @@ -579,8 +605,20 @@ def warn_auto_module_import : Warning< "import of module '%1'">, InGroup<AutoImport>, DefaultIgnore; def warn_uncovered_module_header : Warning< "umbrella header for module '%0' does not include header '%1'">, - InGroup<IncompleteUmbrella>; + InGroup<IncompleteUmbrella>, DefaultIgnore; +def warn_forgotten_module_header : Warning< + "header '%0' is included in module '%1' but not listed in module map">, + InGroup<IncompleteModule>, DefaultIgnore; def err_expected_id_building_module : Error< "expected a module name in '__building_module' expression">; - +def error_use_of_private_header_outside_module : Error< + "use of private header from outside its module: '%0'">; +def error_undeclared_use_of_module : Error< + "use of a module not declared used: '%0'">; + +def warn_header_guard : Warning< + "%0 is used as a header guard here, followed by #define of a different macro">, + InGroup<DiagGroup<"header-guard">>; +def note_header_guard : Note< + "%0 is defined here; did you mean %1?">; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.def b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.def index 41bbff2..a360a5a 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticOptions.def @@ -72,6 +72,7 @@ DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing +DIAGOPT(CLFallbackMode, 1, 0) /// Format for clang-cl fallback mode VALUE_DIAGOPT(ErrorLimit, 32, 0) /// Limit # errors emitted. /// Limit depth of macro expansion backtrace. diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td index e001bd4..2feab52 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -23,6 +23,8 @@ def err_asm_empty : Error<"__asm used with no assembly instructions">; def err_inline_ms_asm_parsing : Error<"%0">; def err_msasm_unsupported_arch : Error< "Unsupported architecture '%0' for MS-style inline assembly">; +def err_msasm_unable_to_create_target : Error< + "MS-style inline assembly is not available: %0">; } let CategoryName = "Parse Issue" in { @@ -54,13 +56,12 @@ def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">, def ext_plain_complex : ExtWarn< "plain '_Complex' requires a type specifier; assuming '_Complex double'">; def ext_integer_complex : Extension< - "complex integer types are a GNU extension">, InGroup<GNU>; + "complex integer types are a GNU extension">, InGroup<GNUComplexInteger>; def ext_thread_before : Extension<"'__thread' before '%0'">; +def ext_keyword_as_ident : ExtWarn< + "keyword '%0' will be treated as an identifier %select{here|for the remainder of the translation unit}1">, + InGroup<KeywordCompat>; -def ext_empty_struct_union : Extension< - "empty %select{struct|union}0 is a GNU extension">, InGroup<GNU>; -def warn_empty_struct_union_compat : Warning<"empty %select{struct|union}0 " - "has size 0 in C, size 1 in C++">, InGroup<CXXCompat>, DefaultIgnore; def error_empty_enum : Error<"use of empty enum">; def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">; def err_invalid_short_spec : Error<"'short %0' is invalid">; @@ -75,8 +76,6 @@ def ext_c99_variable_decl_in_for_loop : Extension< "variable declaration in for loop is a C99-specific feature">, InGroup<C99>; def ext_c99_compound_literal : Extension< "compound literals are a C99-specific feature">, InGroup<C99>; -def ext_c99_flexible_array_member : Extension< - "Flexible array members are a C99-specific feature">, InGroup<C99>; def ext_enumerator_list_comma_c : Extension< "commas at the end of enumerator lists are a C99-specific " "feature">, InGroup<C99>; @@ -103,7 +102,7 @@ def warn_cxx98_compat_alignof : Warning< "alignof expressions are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; def ext_alignof_expr : ExtWarn< - "%0 applied to an expression is a GNU extension">, InGroup<GNU>; + "%0 applied to an expression is a GNU extension">, InGroup<GNUAlignofExpression>; def warn_microsoft_dependent_exists : Warning< "dependent %select{__if_not_exists|__if_exists}0 declarations are ignored">, @@ -123,17 +122,15 @@ def ext_c11_noreturn : Extension< "_Noreturn functions are a C11-specific feature">, InGroup<C11>; def ext_gnu_indirect_goto : Extension< - "use of GNU indirect-goto extension">, InGroup<GNU>; + "use of GNU indirect-goto extension">, InGroup<GNULabelsAsValue>; def ext_gnu_address_of_label : Extension< - "use of GNU address-of-label extension">, InGroup<GNU>; -def ext_gnu_local_label : Extension< - "use of GNU locally declared label extension">, InGroup<GNU>; + "use of GNU address-of-label extension">, InGroup<GNULabelsAsValue>; def ext_gnu_statement_expr : Extension< - "use of GNU statement expression extension">, InGroup<GNU>; + "use of GNU statement expression extension">, InGroup<GNUStatementExpression>; def ext_gnu_conditional_expr : Extension< - "use of GNU ?: expression extension, eliding middle term">, InGroup<GNU>; + "use of GNU ?: conditional expression extension, omitting middle operand">, InGroup<GNUConditionalOmittedOperand>; def ext_gnu_empty_initializer : Extension< - "use of GNU empty initializer extension">, InGroup<GNU>; + "use of GNU empty initializer extension">, InGroup<GNUEmptyInitializer>; def ext_gnu_array_range : Extension<"use of GNU array range extension">, InGroup<GNUDesignator>; def ext_gnu_missing_equal_designator : ExtWarn< @@ -144,7 +141,7 @@ def ext_gnu_old_style_field_designator : ExtWarn< "use of GNU old-style field designator extension">, InGroup<GNUDesignator>; def ext_gnu_case_range : Extension<"use of GNU case range extension">, - InGroup<GNU>; + InGroup<GNUCaseRange>; // Generic errors. def err_expected_expression : Error<"expected expression">; @@ -156,7 +153,7 @@ def err_expected_ident_lparen : Error<"expected identifier or '('">; def err_expected_ident_lbrace : Error<"expected identifier or '{'">; def err_expected_lbrace : Error<"expected '{'">; def err_expected_lparen : Error<"expected '('">; -def err_expected_lparen_or_lbrace : Error<"expected '('or '{'">; +def err_expected_lparen_or_lbrace : Error<"expected '(' or '{'">; def err_expected_rparen : Error<"expected ')'">; def err_expected_lsquare : Error<"expected '['">; def err_expected_rsquare : Error<"expected ']'">; @@ -173,10 +170,6 @@ def err_expected_member_name_or_semi : Error< "expected member name or ';' after declaration specifiers">; def err_function_declared_typedef : Error< "function definition declared 'typedef'">; -def err_iboutletcollection_builtintype : Error< - "type argument of iboutletcollection attribute cannot be a builtin type">; -def err_iboutletcollection_with_protocol : Error< - "invalid argument of iboutletcollection attribute">; def err_at_defs_cxx : Error<"@defs is not supported in Objective-C++">; def err_at_in_class : Error<"unexpected '@' in member specification">; @@ -313,6 +306,11 @@ def err_expected_class_name_not_template : Error<"'typename' is redundant; base classes are implicitly types">; def err_unspecified_vla_size_with_static : Error< "'static' may not be used with an unspecified variable length array size">; +def warn_deprecated_register : Warning< + "'register' storage class specifier is deprecated">, + InGroup<DeprecatedRegister>; +def err_expected_parentheses_around_typename : Error< + "expected parentheses around type name in %0 expression">; def err_expected_case_before_expression: Error< "expected 'case' keyword before expression">; @@ -451,6 +449,7 @@ def err_invalid_operator_on_type : Error< "cannot use %select{dot|arrow}0 operator on a type">; def err_expected_unqualified_id : Error< "expected %select{identifier|unqualified-id}0">; +def err_unexpected_unqualified_id : Error<"type-id cannot have a name">; def err_func_def_no_params : Error< "function definition does not declare parameters">; def err_expected_lparen_after_type : Error< @@ -468,6 +467,10 @@ def err_expected_member_or_base_name : Error< "expected class member or base class name">; def err_expected_lbrace_after_base_specifiers : Error< "expected '{' after base class list">; +def err_missing_end_of_definition : Error< + "missing '}' at end of definition of %q0">; +def note_missing_end_of_definition_before : Note< + "still within definition of %q0 here">; def ext_ellipsis_exception_spec : Extension< "exception specification of '...' is a Microsoft extension">, InGroup<Microsoft>; @@ -482,6 +485,8 @@ def err_expected_rbrace_or_comma : Error<"expected '}' or ','">; def err_expected_rsquare_or_comma : Error<"expected ']' or ','">; def err_using_namespace_in_class : Error< "'using namespace' is not allowed in classes">; +def err_constructor_bad_name : Error< + "missing return type for function %0; did you mean the constructor name %1?">; def err_destructor_tilde_identifier : Error< "expected a class name after '~' to name a destructor">; def err_destructor_template_id : Error< @@ -498,6 +503,9 @@ def err_misplaced_ellipsis_in_declaration : Error< def ext_abstract_pack_declarator_parens : ExtWarn< "ISO C++11 requires a parenthesized pack declaration to have a name">, InGroup<DiagGroup<"anonymous-pack-parens">>; +def err_function_is_not_record : Error< + "unexpected '%select{.|->}0' in function call; perhaps remove the " + "'%select{.|->}0'?">; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; @@ -579,7 +587,7 @@ def err_two_right_angle_brackets_need_space : Error< def err_right_angle_bracket_equal_needs_space : Error< "a space is required between a right angle bracket and an equals sign " "(use '> =')">; -def warn_cxx0x_right_shift_in_template_arg : Warning< +def warn_cxx11_right_shift_in_template_arg : Warning< "use of right-shift operator ('>>') in template argument will require " "parentheses in C++11">, InGroup<CXX11Compat>; def warn_cxx98_compat_two_right_angle_brackets : Warning< @@ -593,6 +601,12 @@ def err_explicit_instantiation_with_definition : Error< "explicit template instantiation cannot have a definition; if this " "definition is meant to be an explicit specialization, add '<>' after the " "'template' keyword">; +def err_template_defn_explicit_instantiation : Error< + "%select{function|class|variable}0 cannot be defined in an explicit instantiation; if this " + "declaration is meant to be a %select{function|class|variable}0 definition, remove the 'template' keyword">; +def err_friend_explicit_instantiation : Error< + "friend cannot be declared in an explicit instantiation; if this " + "declaration is meant to be a friend declaration, remove the 'template' keyword">; def err_explicit_instantiation_enum : Error< "enumerations cannot be explicitly instantiated">; def err_expected_template_parameter : Error<"expected template parameter">; @@ -609,7 +623,7 @@ def warn_cxx98_compat_extern_template : Warning< InGroup<CXX98CompatPedantic>, DefaultIgnore; def warn_static_inline_explicit_inst_ignored : Warning< "ignoring '%select{static|inline}0' keyword on explicit template " - "instantiation">; + "instantiation">, InGroup<DiagGroup<"static-inline-explicit-instantiation">>; // Constructor template diagnostics. def err_out_of_line_constructor_template_id : Error< @@ -693,6 +707,9 @@ def warn_cxx98_compat_override_control_keyword : Warning< InGroup<CXX98Compat>, DefaultIgnore; def err_override_control_interface : Error< "'%0' keyword not permitted with interface types">; +def ext_ms_sealed_keyword : ExtWarn< + "'sealed' keyword is a Microsoft extension">, + InGroup<Microsoft>; def err_access_specifier_interface : Error< "interface types cannot specify '%select{private|protected}0' access">; @@ -783,13 +800,16 @@ 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">; + "'#pragma fp_contract' can only appear at file scope or at the start of a " + "compound statement">; // - #pragma comment def err_pragma_comment_malformed : Error< "pragma comment requires parenthesized identifier and optional string">; def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">; - +// - #pragma detect_mismatch +def err_pragma_detect_mismatch_malformed : Error< + "pragma detect_mismatch is malformed; it requires two comma-separated " + "string literals">; // OpenCL Section 6.8.g def err_not_opencl_storage_class_specifier : Error< @@ -819,13 +839,18 @@ def err_seh___finally_block : Error< def warn_pragma_omp_ignored : Warning < "unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore; def warn_omp_extra_tokens_at_eol : Warning < - "extra tokens at end of '#pragma omp %0' are ignored">, + "extra tokens at the end of '#pragma omp %0' are ignored">, InGroup<ExtraTokens>; def err_omp_unknown_directive : Error < "expected an OpenMP directive">; def err_omp_unexpected_directive : Error < "unexpected OpenMP directive '#pragma omp %0'">; - +def err_omp_expected_punc : Error < + "expected ',' or ')' in %select{'#pragma omp %1'|'%1' clause}0">; +def err_omp_unexpected_clause : Error < + "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">; +def err_omp_more_one_clause : Error < + "directive '#pragma omp %0' cannot contain more than one '%1' clause">; } // end of Parse Issue category. let CategoryName = "Modules Issue" in { diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index f5345eb..6c7cb00 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -18,7 +18,12 @@ let CategoryName = "Semantic Issue" in { def warn_variables_not_in_loop_body : Warning< "variable%select{s| %1|s %1 and %2|s %1, %2, and %3|s %1, %2, %3, and %4}0 " "used in loop condition not modified in loop body">, - InGroup<DiagGroup<"loop-analysis">>, DefaultIgnore; + InGroup<LoopAnalysis>, DefaultIgnore; +def warn_redundant_loop_iteration : Warning< + "variable %0 is %select{decremented|incremented}1 both in the loop header " + "and in the loop body">, + InGroup<LoopAnalysis>, DefaultIgnore; +def note_loop_iteration_here : Note<"%select{decremented|incremented}0 here">; def warn_duplicate_enum_values : Warning< "element %0 has been implicitly assigned %1 which another element has " @@ -30,23 +35,19 @@ def err_expr_not_ice : Error< "expression is not an %select{integer|integral}0 constant expression">; def ext_expr_not_ice : Extension< "expression is not an %select{integer|integral}0 constant expression; " - "folding it to a constant is a GNU extension">, InGroup<GNU>; + "folding it to a constant is a GNU extension">, InGroup<GNUFoldingConstant>; def err_typecheck_converted_constant_expression : Error< "value of type %0 is not implicitly convertible to %1">; def err_typecheck_converted_constant_expression_disallowed : Error< "conversion from %0 to %1 is not allowed in a converted constant expression">; def err_expr_not_cce : Error< - "%select{case value|enumerator value|non-type template argument}0 " + "%select{case value|enumerator value|non-type template argument|array size}0 " "is not a constant expression">; -def err_cce_narrowing : ExtWarn< - "%select{case value|enumerator value|non-type template argument}0 " +def ext_cce_narrowing : ExtWarn< + "%select{case value|enumerator value|non-type template argument|array size}0 " "%select{cannot be narrowed from type %2 to %3|" "evaluates to %2, which cannot be narrowed to type %3}1">, - InGroup<CXX11Narrowing>, DefaultError; -def err_cce_narrowing_sfinae : Error< - "%select{case value|enumerator value|non-type template argument}0 " - "%select{cannot be narrowed from type %2 to %3|" - "evaluates to %2, which cannot be narrowed to type %3}1">; + InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure; def err_ice_not_integral : Error< "integral constant expression must have integral or unscoped enumeration " "type, not %0">; @@ -78,9 +79,6 @@ def ext_vla : Extension<"variable length arrays are a C99 feature">, InGroup<VLAExtension>; def warn_vla_used : Warning<"variable length array used">, InGroup<VLA>, DefaultIgnore; -def warn_cxx11_compat_array_of_runtime_bound : Warning< - "arrays of runtime bound are incompatible with C++ standards before C++1y">, - InGroup<CXXPre1yCompatPedantic>, DefaultIgnore; def err_vla_non_pod : Error<"variable length array of non-POD element type %0">; def err_vla_in_sfinae : Error< "variable length array cannot be formed during template argument deduction">; @@ -93,7 +91,7 @@ def err_vla_decl_has_static_storage : Error< def err_vla_decl_has_extern_linkage : Error< "variable length array declaration can not have 'extern' linkage">; def ext_vla_folded_to_constant : Extension< - "variable length array folded to constant array as an extension">; + "variable length array folded to constant array as an extension">, InGroup<GNUFoldingConstant>; // C99 variably modified types def err_variably_modified_template_arg : Error< @@ -138,7 +136,7 @@ def err_designator_into_flexible_array_member : Error< def note_flexible_array_member : Note< "initialized flexible array member %0 is here">; def ext_flexible_array_init : Extension< - "flexible array initialization is a GNU extension">, InGroup<GNU>; + "flexible array initialization is a GNU extension">, InGroup<GNUFlexibleArrayInitializer>; // Declarations. def err_bad_variable_name : Error< @@ -150,6 +148,12 @@ def warn_unused_parameter : Warning<"unused parameter %0">, InGroup<UnusedParameter>, DefaultIgnore; def warn_unused_variable : Warning<"unused variable %0">, InGroup<UnusedVariable>, DefaultIgnore; +def warn_unused_property_backing_ivar : + Warning<"ivar %0 which backs the property is not " + "referenced in this property's accessor">, + InGroup<UnusedPropertyIvar>, DefaultIgnore; +def warn_unused_const_variable : Warning<"unused variable %0">, + InGroup<UnusedConstVariable>, DefaultIgnore; def warn_unused_exception_param : Warning<"unused exception parameter %0">, InGroup<UnusedExceptionParameter>, DefaultIgnore; def warn_decl_in_param_list : Warning< @@ -287,6 +291,18 @@ def note_using_decl : Note<"%select{|previous }0using declaration">; def warn_access_decl_deprecated : Warning< "access declarations are deprecated; use using declarations instead">, InGroup<Deprecated>; +def err_access_decl : Error< + "ISO C++11 does not allow access declarations; " + "use using declarations instead">; +def warn_exception_spec_deprecated : Warning< + "dynamic exception specifications are deprecated">, + InGroup<Deprecated>, DefaultIgnore; +def note_exception_spec_deprecated : Note<"use '%0' instead">; +def warn_deprecated_copy_operation : Warning< + "definition of implicit copy %select{constructor|assignment operator}1 " + "for %0 is deprecated because it has a user-declared " + "%select{copy %select{assignment operator|constructor}1|destructor}2">, + InGroup<Deprecated>, DefaultIgnore; def warn_global_constructor : Warning< "declaration requires a global constructor">, @@ -400,7 +416,7 @@ def ext_noreturn_main : ExtWarn< def note_main_remove_noreturn : Note<"remove '_Noreturn'">; def err_constexpr_main : Error< "'main' is not allowed to be declared constexpr">; -def err_main_template_decl : Error<"'main' cannot be a template">; +def err_mainlike_template_decl : Error<"'%0' cannot be a template">; def err_main_returns_nonint : Error<"'main' must return 'int'">; def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">, InGroup<MainReturnType>; @@ -447,6 +463,7 @@ def warn_pragma_pack_show : Warning<"value of #pragma pack(show) == %0">; def warn_pragma_pack_pop_identifer_and_alignment : Warning< "specifying both a name and alignment to 'pop' is undefined">; def warn_pragma_pack_pop_failed : Warning<"#pragma pack(pop, ...) failed: %0">; +def warn_pragma_ms_struct_failed : Warning<"#pramga ms_struct can not be used with dynamic classes or structures">, InGroup<IgnoredAttributes>; def warn_pragma_unused_undeclared_var : Warning< "undeclared variable %0 used as an argument for '#pragma unused'">; @@ -472,7 +489,6 @@ def err_no_nsconstant_string_class : Error< "cannot find interface declaration for %0">; def err_recursive_superclass : Error< "trying to recursively use %0 as superclass of %1">; -def warn_previous_alias_decl : Warning<"previously declared alias is ignored">; def err_conflicting_aliasing_type : Error<"conflicting types for alias %0">; def warn_undef_interface : Warning<"cannot find interface declaration for %0">; def warn_duplicate_protocol_def : Warning<"duplicate protocol definition of %0 is ignored">; @@ -488,6 +504,9 @@ def warn_property_attribute : Warning< "'%1' attribute on property %0 does not match the property inherited from %2">; def warn_property_types_are_incompatible : Warning< "property type %0 is incompatible with type %1 inherited from %2">; +def warn_protocol_property_mismatch : Warning< + "property of type %0 was selected for synthesis">, + InGroup<DiagGroup<"protocol-property-synthesis-ambiguity">>; def err_undef_interface : Error<"cannot find interface declaration for %0">; def err_category_forward_interface : Error< "cannot define %select{category|class extension}0 for undefined class %1">; @@ -499,6 +518,8 @@ def note_while_in_implementation : Note< "detected while default synthesizing properties in class implementation">; def note_class_declared : Note< "class is declared here">; +def note_receiver_class_declared : Note< + "receiver is instance of class declared here">; def note_receiver_is_id : Note< "receiver is treated with 'id' type for purpose of method lookup">; def note_suppressed_class_declare : Note< @@ -506,7 +527,7 @@ def note_suppressed_class_declare : Note< def err_objc_root_class_subclass : Error< "objc_root_class attribute may only be specified on a root class declaration">; def warn_objc_root_class_missing : Warning< - "class %0 defined without specifying a base class">, + "class %0 defined without specifying a base class">, InGroup<ObjCRootClass>; def note_objc_needs_superclass : Note< "add a super class to fix this problem">; @@ -645,12 +666,18 @@ def warn_objc_isa_assign : Warning< def warn_objc_pointer_masking : Warning< "bitmasking for introspection of Objective-C object pointers is strongly " "discouraged">, - InGroup<DiagGroup<"deprecated-objc-pointer-introspection">>; + InGroup<ObjCPointerIntrospect>; +def warn_objc_pointer_masking_performSelector : Warning<warn_objc_pointer_masking.Text>, + InGroup<ObjCPointerIntrospectPerformSelector>; def warn_objc_property_default_assign_on_object : Warning< "default property attribute 'assign' not appropriate for non-GC object">, InGroup<ObjCPropertyNoAttribute>; def warn_property_attr_mismatch : Warning< "property attribute in class extension does not match the primary class">; +def warn_property_implicitly_mismatched : Warning < + "primary property declaration is implicitly strong while redeclaration " + "in class extension is weak">, + InGroup<DiagGroup<"objc-property-implicit-mismatch">>; def warn_objc_property_copy_missing_on_block : Warning< "'copy' attribute must be specified for the block property " "when -fobjc-gc-only is specified">; @@ -727,6 +754,8 @@ def error_category_property : Error< "class implementation">; def note_property_declare : Note< "property declared here">; +def note_protocol_property_declare : Note< + "it could also be property of type %0 declared here">; def note_property_synthesize : Note< "property synthesized here">; def error_synthesize_category_decl : Error< @@ -804,6 +833,9 @@ def error_dealloc_bad_result_type : Error< "instead of %0">; def warn_undeclared_selector : Warning< "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore; +def warn_undeclared_selector_with_typo : Warning< + "undeclared selector %0; did you mean %1?">, + InGroup<UndeclaredSelector>, DefaultIgnore; def warn_implicit_atomic_property : Warning< "property is assumed atomic by default">, InGroup<ImplicitAtomic>, DefaultIgnore; def note_auto_readonly_iboutlet_fixup_suggest : Note< @@ -813,10 +845,12 @@ def warn_auto_readonly_iboutlet_property : Warning< "not work correctly with 'nib' loader">, InGroup<DiagGroup<"readonly-iboutlet-property">>; def warn_auto_implicit_atomic_property : Warning< - "property is assumed atomic when auto-synthesizing the property">, + "property is assumed atomic when auto-synthesizing the property">, InGroup<ImplicitAtomic>, DefaultIgnore; def warn_unimplemented_selector: Warning< - "unimplemented selector %0">, InGroup<Selector>, DefaultIgnore; + "creating selector for nonexistent method %0">, InGroup<Selector>, DefaultIgnore; +def warning_multiple_selectors: Warning< + "multiple selectors named %0 found">, InGroup<SelectorTypeMismatch>, DefaultIgnore; def warn_unimplemented_protocol_method : Warning< "method %0 in protocol not implemented">, InGroup<Protocol>; @@ -834,7 +868,7 @@ def err_inline_namespace_mismatch : Error< def err_unexpected_friend : Error< "friends can only be classes or functions">; def ext_enum_friend : ExtWarn< - "enumeration type %0 cannot be a friend">; + "befriending enumeration type %0 is a C++11 extension">, InGroup<CXX11>; def warn_cxx98_compat_enum_friend : Warning< "befriending enumeration type %0 is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; @@ -865,7 +899,7 @@ 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 %3?">; def err_partial_specialization_friend : Error< "partial specialization cannot be declared as a friend">; def err_qualified_friend_def : Error< @@ -876,6 +910,14 @@ def err_friend_not_first_in_declaration : Error< "'friend' must appear first in a non-function declaration">; def err_using_decl_friend : Error< "cannot befriend target of using declaration">; +def warn_template_qualified_friend_unsupported : Warning< + "dependent nested name specifier '%0' for friend class declaration is " + "not supported; turning off access control for %1">, + InGroup<UnsupportedFriend>; +def warn_template_qualified_friend_ignored : Warning< + "dependent nested name specifier '%0' for friend template declaration is " + "not supported; ignoring this friend declaration">, + InGroup<UnsupportedFriend>; def err_invalid_member_in_interface : Error< "%select{data member |non-public member function |static member function |" @@ -886,12 +928,15 @@ def err_invalid_base_in_interface : Error< "%select{'struct|non-public 'interface|'class}0 %1'">; def err_abstract_type_in_decl : Error< - "%select{return|parameter|variable|field|instance variable}0 type %1 is an abstract class">; + "%select{return|parameter|variable|field|instance variable|" + "synthesized 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< "cannot throw an object of abstract type %0">; def err_array_of_abstract_type : Error<"array of abstract class type %0">; +def err_capture_of_abstract_type : Error< + "by-copy capture of value of abstract type %0">; def err_multiple_final_overriders : Error< "virtual function %q0 has more than one final overrider in %1">; @@ -999,8 +1044,8 @@ def err_access_dtor_base : Error<"base class %0 has %select{private|protected}1 destructor">, AccessControl; def err_access_dtor_vbase : - Error<"inherited virtual base class %0 has " - "%select{private|protected}1 destructor">, + Error<"inherited virtual base class %1 has " + "%select{private|protected}2 destructor">, AccessControl; def err_access_dtor_temp : Error<"temporary of type %0 has %select{private|protected}1 destructor">, @@ -1086,6 +1131,8 @@ def err_explicit_non_ctor_or_conv_function : Error< def err_static_not_bitfield : Error<"static member %0 cannot be a bit-field">; def err_static_out_of_line : Error< "'static' can only be specified inside the class definition">; +def err_storage_class_for_static_member : Error< + "static data member definition cannot specify a storage class">; def err_typedef_not_bitfield : Error<"typedef member %0 cannot be a bit-field">; def err_not_integral_type_bitfield : Error< "bit-field %0 has non-integral type %1">; @@ -1114,7 +1161,7 @@ def note_bitfield_decl : Note<"bit-field is declared here">; def note_previous_decl : Note<"%0 declared here">; def note_implicit_param_decl : Note<"%0 is an implicit parameter">; def note_member_synthesized_at : Note< - "implicit default %select{constructor|copy constructor|move constructor|copy " + "implicit %select{default constructor|copy constructor|move constructor|copy " "assignment operator|move assignment operator|destructor}0 for %1 first " "required here">; def note_inhctor_synthesized_at : Note< @@ -1172,6 +1219,9 @@ def ext_static_data_member_in_union : ExtWarn< def warn_cxx98_compat_static_data_member_in_union : Warning< "static data member %0 in union is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; +def ext_union_member_of_reference_type : ExtWarn< + "union member %0 has reference type %1, which is a Microsoft extension">, + InGroup<Microsoft>; def err_union_member_of_reference_type : Error< "union member %0 has reference type %1">; def ext_anonymous_struct_union_qualified : Extension< @@ -1261,7 +1311,9 @@ def err_destructor_template : Error< def err_init_conversion_failed : Error< "cannot initialize %select{a variable|a parameter|return object|an " "exception object|a member subobject|an array element|a new value|a value|a " - "base class|a constructor delegation|a vector element}0 " + "base class|a constructor delegation|a vector element|a block element|a " + "complex element|a lambda capture|a compound literal initializer|a " + "related result|a parameter of CF audited function}0 " "%diff{of type $ with an %select{rvalue|lvalue}2 of type $|" "with an %select{rvalue|lvalue}2 of incompatible type}1,3" "%select{|: different classes%diff{ ($ vs $)|}5,6" @@ -1330,6 +1382,9 @@ def warn_field_is_uninit : Warning<"field %0 is uninitialized when used here">, def warn_reference_field_is_uninit : Warning< "reference %0 is not yet bound to a value when used here">, InGroup<Uninitialized>; +def note_uninit_in_this_constructor : Note< + "during field initialization in %select{this|the implicit default}0 " + "constructor">; def warn_static_self_reference_in_init : Warning< "static variable %0 is suspiciously used within its own initialization">, InGroup<UninitializedStaticSelfInit>; @@ -1348,7 +1403,10 @@ def warn_sometimes_uninit_var : Warning< "%select{'%3' condition is %select{true|false}4|" "'%3' loop %select{is entered|exits because its condition is false}4|" "'%3' loop %select{condition is true|exits because its condition is false}4|" - "switch %3 is taken}2">, InGroup<UninitializedSometimes>, DefaultIgnore; + "switch %3 is taken|" + "its declaration is reached|" + "%3 is called}2">, + InGroup<UninitializedSometimes>, DefaultIgnore; def warn_maybe_uninit_var : Warning< "variable %0 may be uninitialized when " "%select{used here|captured by block}1">, @@ -1425,11 +1483,14 @@ def err_illegal_decl_array_of_auto : Error< 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" + "%select{'auto'|'decltype(auto)'}0 not allowed %select{in function prototype" + "|in non-static struct member" "|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" - "|in conversion function type|here}0">; + "|in conversion function type|here|in lambda parameter}1">; +def err_auto_not_allowed_var_inst : Error< + "'auto' variable template instantiation is not allowed">; 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< @@ -1498,19 +1559,22 @@ def err_auto_fn_virtual : Error< // C++11 override control def override_keyword_only_allowed_on_virtual_member_functions : Error< "only virtual member functions can be marked '%0'">; +def override_keyword_hides_virtual_member_function : Error< + "non-virtual member function marked '%0' hides virtual member " + "%select{function|functions}1">; 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'">; + "base %0 is marked '%select{final|sealed}1'">; def warn_abstract_final_class : Warning< - "abstract class is marked 'final'">, InGroup<AbstractFinalClass>; + "abstract class is marked '%select{final|sealed}0'">, InGroup<AbstractFinalClass>; // C++11 attributes def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">; // C++11 final def err_final_function_overridden : Error< - "declaration of %0 overrides a 'final' function">; + "declaration of %0 overrides a '%select{final|sealed}1' function">; // C++11 scoped enumerations def err_enum_invalid_underlying : Error< @@ -1572,6 +1636,9 @@ def note_in_for_range: Note< def err_for_range_invalid: Error< "invalid range expression of type %0; no viable '%select{begin|end}1' " "function available">; +def err_range_on_array_parameter : Error< + "cannot build range expression with array function parameter %0 since " + "parameter with array type %1 is treated as pointer type %2">; def err_for_range_dereference : Error< "invalid range expression of type %0; did you mean to dereference it " "with '*'?">; @@ -1725,8 +1792,8 @@ def err_attribute_can_be_applied_only_to_symbol_declaration : Error< def err_attributes_are_not_compatible : Error< "%0 and %1 attributes are not compatible">; def err_attribute_wrong_number_arguments : Error< - "attribute %plural{0:takes no arguments|1:takes one argument|" - ":requires exactly %0 arguments}0">; + "%0 attribute %plural{0:takes no arguments|1:takes one argument|" + ":requires exactly %1 arguments}1">; def err_attribute_too_many_arguments : Error< "attribute takes no more than %0 argument%s0">; def err_suppress_autosynthesis : Error< @@ -1734,13 +1801,11 @@ def err_suppress_autosynthesis : Error< "to a class declaration">; def err_attribute_too_few_arguments : Error< "attribute takes at least %0 argument%s0">; -def err_attribute_missing_parameter_name : Error< - "attribute requires unquoted parameter">; def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; def err_attribute_bad_neon_vector_size : Error< "Neon vector size must be 64 or 128 bits">; -def err_attribute_argument_not_int : Error< - "'%0' attribute requires integer constant">; +def err_attribute_unsupported : Error< + "%0 attribute is not supported for this target">; def err_aligned_attribute_argument_not_int : Error< "'aligned' attribute requires integer constant">; def err_alignas_attribute_wrong_decl_type : Error< @@ -1756,8 +1821,12 @@ def err_alignas_mismatch : Error< "redeclaration has different alignment requirement (%1 vs %0)">; def err_alignas_underaligned : Error< "requested alignment is less than minimum alignment of %1 for type %0">; -def err_attribute_first_argument_not_int_or_bool : Error< - "%0 attribute first argument must be of int or bool type">; +def err_attribute_argument_n_type : Error< + "%0 attribute requires parameter %1 to be %select{int or bool|an integer " + "constant|a string|an identifier}2">; +def err_attribute_argument_type : Error< + "%0 attribute requires %select{int or bool|an integer " + "constant|a string|an identifier}1">; def err_attribute_argument_outof_range : Error< "init_priority attribute requires integer constant between " "101 and 65535 inclusive">; @@ -1766,26 +1835,20 @@ def err_init_priority_object_attr : Error< "of objects of class type">; def err_attribute_argument_vec_type_hint : Error< "invalid attribute argument %0 - expecting a vector or vectorizable scalar type">; -def err_attribute_argument_n_not_int : Error< - "'%0' attribute requires parameter %1 to be an integer constant">; -def err_attribute_argument_n_not_string : Error< - "'%0' attribute requires parameter %1 to be a string">; -def err_attribute_argument_n_not_identifier : Error< - "'%0' attribute requires parameter %1 to be an identifier">; def err_attribute_argument_out_of_bounds : Error< "'%0' attribute parameter %1 is out of bounds">; -def err_attribute_requires_objc_interface : Error< - "attribute may only be applied to an Objective-C interface">; def err_attribute_uuid_malformed_guid : Error< "uuid attribute contains a malformed GUID">; def warn_nonnull_pointers_only : Warning< "nonnull attribute only applies to pointer arguments">; def err_attribute_pointers_only : Error< - "'%0' attribute only applies to pointer arguments">; + "%0 attribute only applies to pointer arguments">; +def err_attribute_no_member_pointers : Error< + "%0 attribute cannot be used with pointers to members">; def err_attribute_invalid_implicit_this_argument : Error< "'%0' attribute is invalid for the implicit this argument">; def err_ownership_type : Error< - "%0 attribute only applies to %1 arguments">; + "%0 attribute only applies to %select{pointer|integer}1 arguments">; def err_format_strftime_third_parameter : Error< "strftime format attribute requires 3rd parameter to be 0">; def err_format_attribute_requires_variadic : Error< @@ -1795,12 +1858,14 @@ def err_format_attribute_result_not : Error<"function does not return %0">; def err_format_attribute_implicit_this_format_string : Error< "format attribute cannot specify the implicit this argument as the format " "string">; -def warn_unknown_method_family : Warning<"unrecognized method family">; +def err_common_not_supported_cplusplus : Error< + "common attribute is not supported in C++">; def err_init_method_bad_return_type : Error< "init methods must return an object pointer type, not %0">; def err_attribute_invalid_size : Error< "vector size not an integral multiple of component size">; def err_attribute_zero_size : Error<"zero vector size">; +def err_attribute_size_too_large : Error<"vector size too large">; def err_typecheck_vector_not_convertable : Error< "can't convert between vector values of different size (%0 and %1)">; def err_typecheck_ext_vector_not_typedef : Error< @@ -1809,8 +1874,6 @@ def err_ext_vector_component_exceeds_length : Error< "vector component access exceeds type %0">; def err_ext_vector_component_name_illegal : Error< "illegal vector component name '%0'">; -def err_attribute_address_space_not_int : Error< - "address space attribute requires an integer constant">; def err_attribute_address_space_negative : Error< "address space is negative">; def err_attribute_address_space_too_high : Error< @@ -1827,8 +1890,6 @@ def err_field_with_address_space : Error< "field may not be qualified with an address space">; def err_attr_objc_ownership_redundant : Error< "the type %0 is already explicitly ownership-qualified">; -def err_attribute_not_string : Error< - "argument to %0 attribute was not a string literal">; def err_undeclared_nsnumber : Error< "NSNumber must be available to use Objective-C literals">; def err_invalid_nsnumber_type : Error< @@ -1862,9 +1923,15 @@ def warn_objc_literal_comparison : Warning< "direct comparison of %select{an array literal|a dictionary literal|" "a numeric literal|a boxed expression|}0 has undefined behavior">, InGroup<ObjCLiteralComparison>; +def warn_missing_atsign_prefix : Warning< + "string literal must be prefixed by '@' ">, InGroup<ObjCLiteralMissingAtSign>; def warn_objc_string_literal_comparison : Warning< "direct comparison of a string literal has undefined behavior">, InGroup<ObjCStringComparison>; +def warn_concatenated_nsarray_literal : Warning< + "concatenated NSString literal for an NSArray expression - " + "possibly missing a comma">, + InGroup<ObjCStringConcatenation>; def note_objc_literal_comparison_isequal : Note< "use 'isEqual:' instead">; @@ -1948,8 +2015,10 @@ def warn_weak_identifier_undeclared : Warning< "weak identifier %0 never declared">; def err_attribute_weak_static : Error< "weak declaration cannot have internal linkage">; -def warn_attribute_weak_import_invalid_on_definition : Warning< - "'weak_import' attribute cannot be specified on a definition">, +def err_attribute_selectany_non_extern_data : Error< + "'selectany' can only be applied to data items with external linkage">; +def warn_attribute_invalid_on_definition : Warning< + "'%0' attribute cannot be specified on a definition">, InGroup<IgnoredAttributes>; def err_attribute_weakref_not_static : Error< "weakref declaration must have internal linkage">; @@ -1959,6 +2028,12 @@ def err_attribute_weakref_without_alias : Error< "weakref declaration of '%0' must also have an alias attribute">; def err_alias_not_supported_on_darwin : Error < "only weak aliases are supported on darwin">; +def err_alias_to_undefined : Error< + "alias must point to a defined variable or function">; +def err_duplicate_mangled_name : Error< + "definition with same mangled name as another definition">; +def err_cyclic_alias : Error< + "alias definition is part of a cycle">; def warn_attribute_wrong_decl_type : Warning< "%0 attribute only applies to %select{functions|unions|" "variables and functions|functions and methods|parameters|" @@ -1967,7 +2042,7 @@ def warn_attribute_wrong_decl_type : Warning< "variables, functions and labels|fields and global variables|structs|" "variables, functions and tag types|thread-local variables|" "variables and fields|variables, data members and tag types|" - "types and namespaces}1">, + "types and namespaces|Objective-C interfaces}1">, InGroup<IgnoredAttributes>; def err_attribute_wrong_decl_type : Error< "%0 attribute only applies to %select{functions|unions|" @@ -1977,15 +2052,11 @@ def err_attribute_wrong_decl_type : Error< "variables, functions and labels|fields and global variables|structs|" "variables, functions and tag types|thread-local variables|" "variables and fields|variables, data members and tag types|" - "types and namespaces}1">; -def warn_function_attribute_wrong_type : Warning< - "'%0' only applies to function types; type here is %1">, - InGroup<IgnoredAttributes>; -def warn_pointer_attribute_wrong_type : Warning< - "'%0' only applies to pointer types; type here is %1">, - InGroup<IgnoredAttributes>; -def warn_objc_object_attribute_wrong_type : Warning< - "'%0' only applies to Objective-C object or block pointer types; type here is %1">, + "types and namespaces|Objective-C interfaces|" + "methods and properties|struct or union|struct, union or class}1">; +def warn_type_attribute_wrong_type : Warning< + "'%0' only applies to %select{function|pointer|" + "Objective-C object or block pointer}1 types; type here is %2">, InGroup<IgnoredAttributes>; def warn_attribute_requires_functions_or_static_globals : Warning< "%0 only applies to variables with static storage duration and functions">, @@ -2007,6 +2078,9 @@ def err_cconv_knr : Error< "function with no prototype cannot use %0 calling convention">; def err_cconv_varargs : Error< "variadic function cannot use %0 calling convention">; +def warn_cconv_varargs : Warning< + "%0 calling convention ignored on variadic function">, + InGroup<IgnoredAttributes>; def err_regparm_mismatch : Error<"function declared with regparm(%0) " "attribute was previously declared " "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">; @@ -2148,6 +2222,32 @@ def note_found_mutex_near_match : Note<"found near match '%0'">; def warn_thread_safety_beta : Warning< "Thread safety beta warning.">, InGroup<ThreadSafetyBeta>, DefaultIgnore; +// Consumed warnings +def warn_use_in_invalid_state : Warning< + "invalid invocation of method '%0' on object '%1' while it is in the '%2' " + "state">, InGroup<Consumed>, DefaultIgnore; +def warn_use_of_temp_in_invalid_state : Warning< + "invalid invocation of method '%0' on a temporary object while it is in the " + "'%1' state">, InGroup<Consumed>, DefaultIgnore; +def warn_attr_on_unconsumable_class : Warning< + "consumed analysis attribute is attached to member of class '%0' which isn't " + "marked as consumable">, InGroup<Consumed>, DefaultIgnore; +def warn_return_typestate_for_unconsumable_type : Warning< + "return state set for an unconsumable type '%0'">, InGroup<Consumed>, + DefaultIgnore; +def warn_return_typestate_mismatch : Warning< + "return value not in expected state; expected '%0', observed '%1'">, + InGroup<Consumed>, DefaultIgnore; +def warn_loop_state_mismatch : Warning< + "state of variable '%0' must match at the entry and exit of loop">, + InGroup<Consumed>, DefaultIgnore; +def warn_param_return_typestate_mismatch : Warning< + "parameter '%0' not in expected state when the function returns: expected " + "'%1', observed '%2'">, InGroup<Consumed>, DefaultIgnore; +def warn_param_typestate_mismatch : Warning< + "argument not in expected state; expected '%0', observed '%1'">, + InGroup<Consumed>, DefaultIgnore; + def warn_impcast_vector_scalar : Warning< "implicit conversion turns vector to scalar: %0 to %1">, InGroup<Conversion>, DefaultIgnore; @@ -2211,9 +2311,17 @@ def warn_cast_align : Warning< "cast from %0 to %1 increases required alignment from %2 to %3">, InGroup<CastAlign>, DefaultIgnore; +// Separate between casts to void* and non-void* pointers. +// Some APIs use (abuse) void* for something like a user context, +// and often that value is an integer even if it isn't a pointer itself. +// Having a separate warning flag allows users to control the warning +// for their workflow. def warn_int_to_pointer_cast : Warning< "cast to %1 from smaller integer type %0">, InGroup<IntToPointerCast>; +def warn_int_to_void_pointer_cast : Warning< + "cast to %1 from smaller integer type %0">, + InGroup<IntToVoidPointerCast>; def warn_attribute_ignored_for_field_of_type : Warning< "%0 attribute ignored for field of type %1">, @@ -2238,16 +2346,14 @@ def warn_transparent_union_attribute_zero_fields : Warning< "transparent_union attribute ignored">, InGroup<IgnoredAttributes>; def warn_attribute_type_not_supported : Warning< - "'%0' attribute argument not supported: %1">, + "%0 attribute argument not supported: %1">, InGroup<IgnoredAttributes>; -def warn_attribute_unknown_visibility : Warning<"unknown visibility '%0'">, +def warn_attribute_unknown_visibility : Warning<"unknown visibility %0">, InGroup<IgnoredAttributes>; def warn_attribute_protected_visibility : Warning<"target does not support 'protected' visibility; using 'default'">, InGroup<DiagGroup<"unsupported-visibility">>; def err_mismatched_visibility: Error<"visibility does not match previous declaration">; -def warn_attribute_unknown_endian : Warning<"unknown endian '%0'">, - InGroup<IgnoredAttributes>; def note_previous_attribute : Note<"previous attribute is here">; def err_unknown_machine_mode : Error<"unknown machine mode %0">; def err_unsupported_machine_mode : Error<"unsupported machine mode %0">; @@ -2273,10 +2379,12 @@ def err_attribute_sentinel_less_than_zero : Error< "'sentinel' parameter 1 less than zero">; def err_attribute_sentinel_not_zero_or_one : Error< "'sentinel' parameter 2 not 0 or 1">; -def err_attribute_cleanup_arg_not_found : Error< - "'cleanup' argument %0 not found">; +def warn_cleanup_ext : Warning< + "GCC does not allow the 'cleanup' attribute argument to be anything other " + "than a simple identifier">, + InGroup<GccCompat>; def err_attribute_cleanup_arg_not_function : Error< - "'cleanup' argument %0 is not a function">; + "'cleanup' argument %select{|%1 |%1 }0is not a %select{||single }0function">; def err_attribute_cleanup_func_must_take_one_arg : Error< "'cleanup' function %0 must take 1 parameter">; def err_attribute_cleanup_func_arg_incompatible_type : Error< @@ -2297,10 +2405,15 @@ def warn_attribute_ibaction: Warning< InGroup<IgnoredAttributes>; def err_iboutletcollection_type : Error< "invalid type %0 as argument of iboutletcollection attribute">; +def err_iboutletcollection_builtintype : Error< + "type argument of iboutletcollection attribute cannot be a builtin type">; def warn_iboutlet_object_type : Warning< "%select{instance variable|property}2 with %0 attribute must " - "be an object type (invalid %1)">, - InGroup<DiagGroup<"invalid-iboutlet">>; + "be an object type (invalid %1)">, InGroup<ObjCInvalidIBOutletProperty>; +def warn_iboutletcollection_property_assign : Warning< + "IBOutletCollection properties should be copy/strong and not assign">, + InGroup<ObjCInvalidIBOutletProperty>; + def err_attribute_overloadable_not_function : Error< "'overloadable' attribute can only be applied to a function">; def err_attribute_overloadable_missing : Error< @@ -2311,7 +2424,7 @@ def note_attribute_overloadable_prev_overload : Note< def err_attribute_overloadable_no_prototype : Error< "'overloadable' function %0 must have a prototype">; def warn_ns_attribute_wrong_return_type : Warning< - "%0 attribute only applies to %select{functions|methods}1 that " + "%0 attribute only applies to %select{functions|methods|properties}1 that " "return %select{an Objective-C object|a pointer|a non-retainable pointer}2">, InGroup<IgnoredAttributes>; def warn_ns_attribute_wrong_parameter_type : Warning< @@ -2326,6 +2439,18 @@ def note_protocol_decl : Note< def err_ns_bridged_not_interface : Error< "parameter of 'ns_bridged' attribute does not name an Objective-C class">; + +// objc_bridge attribute diagnostics. +def err_objc_bridge_not_id : Error< + "parameter of 'objc_bridge' attribute must be a single name of an Objective-C class">; +def err_objc_cf_bridged_not_interface : Error< + "CF object of type %0 is bridged to '%1', which is not an Objective-C class">; +def err_objc_ns_bridged_invalid_cfobject : Error< + "ObjectiveC object of type %0 is bridged to %1, which is not valid CF object">; +def warn_objc_invalid_bridge : Warning< + "%0 bridges to %1, not %2">, InGroup<ObjCBridge>; +def warn_objc_invalid_bridge_to_cf : Warning< + "%0 cannot bridge to %1">, InGroup<ObjCBridge>; // Function Parameter Semantic Analysis. def err_param_with_void_type : Error<"argument may not have 'void' type">; @@ -2366,8 +2491,8 @@ def err_param_default_argument_member_template_redecl : Error< "of a %select{class template|class template partial specialization|nested " "class in a template}0">; def err_uninitialized_member_for_assign : Error< - "cannot define the implicit default assignment operator for %0, because " - "non-static %select{reference|const}1 member %2 can't use default " + "cannot define the implicit copy assignment operator for %0, because " + "non-static %select{reference|const}1 member %2 can't use copy " "assignment operator">; def err_uninitialized_member_in_ctor : Error< "%select{|implicit default |inheriting }0constructor for %1 must explicitly " @@ -2688,6 +2813,7 @@ def err_ovl_ambiguous_oper_unary : Error< def err_ovl_ambiguous_oper_binary : Error< "use of overloaded operator '%0' is ambiguous (with operand types %1 and %2)">; def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">; +def note_assign_lhs_incomplete : Note<"type %0 is incomplete">; def err_ovl_deleted_oper : Error< "overload resolution selected %select{unavailable|deleted}0 operator '%1'%2">; def err_ovl_deleted_special_oper : Error< @@ -2731,7 +2857,8 @@ def err_addr_ovl_no_qualifier : Error< def err_ovl_no_viable_literal_operator : Error< "no matching literal operator for call to %0" "%select{| with argument of type %2| with arguments of types %2 and %3}1" - "%select{| or 'const char *', and no matching literal operator template}4">; + "%select{| or 'const char *'}4" + "%select{|, and no matching literal operator template}5">; // C++ Template Declarations def err_template_param_shadow : Error< @@ -2741,6 +2868,8 @@ def warn_template_export_unsupported : Warning< "exported templates are unsupported">; def err_template_outside_namespace_or_class_scope : Error< "templates can only be declared in namespace or class scope">; +def err_template_inside_local_class : Error< + "templates cannot be declared inside of a local class">; def err_template_linkage : Error<"templates must have C++ linkage">; def err_template_typedef : Error<"a typedef cannot be a template">; def err_template_unnamed_class : Error< @@ -2789,7 +2918,11 @@ def err_template_parameter_default_friend_template : Error< def err_template_template_parm_no_parms : Error< "template template parameter must have its own template parameters">; -def err_template_variable : Error<"variable %0 declared as a template">; +def ext_variable_template : ExtWarn<"variable templates are a C++1y extension">, + InGroup<CXX1y>; +def warn_cxx11_compat_variable_template : Warning< + "variable templates are incompatible with C++ standards before C++1y">, + InGroup<CXXPre1yCompat>, DefaultIgnore; def err_template_variable_noparams : Error< "extraneous 'template<>' in declaration of variable %0">; def err_template_member : Error<"member %0 declared as a template">; @@ -2798,7 +2931,7 @@ def err_template_member_noparams : Error< def err_template_tag_noparams : Error< "extraneous 'template<>' in declaration of %0 %1">; def err_template_decl_ref : Error< - "cannot refer to class template %0 without a template argument list">; + "cannot refer to %select{class|variable}0 template %1 without a template argument list">; // C++ Template Argument Lists def err_template_missing_args : Error< @@ -2879,9 +3012,6 @@ def err_template_arg_ref_bind_ignores_quals : Error< "ignores qualifiers">; def err_template_arg_not_decl_ref : Error< "non-type template argument does not refer to any declaration">; -def err_template_arg_not_object_or_func_form : Error< - "non-type template argument does not directly refer to an object or " - "function">; def err_template_arg_not_address_of : Error< "non-type template argument for template parameter of pointer type %0 must " "have its address taken">; @@ -2926,11 +3056,14 @@ def err_pointer_to_member_call_drops_quals : Error< def err_pointer_to_member_oper_value_classify: Error< "pointer-to-member function type %0 can only be called on an " "%select{rvalue|lvalue}1">; +def ext_ms_deref_template_argument: ExtWarn< + "non-type template argument containing a dereference operation is a " + "Microsoft extension">, InGroup<Microsoft>; // C++ template specialization def err_template_spec_unknown_kind : Error< "can only provide an explicit specialization for a class template, function " - "template, or a member function, static data member, " + "template, variable template, or a member function, static data member, " "%select{or member class|member class, or member enumeration}0 of a " "class template">; def note_specialized_entity : Note< @@ -2942,29 +3075,35 @@ def err_template_spec_decl_class_scope : Error< def err_template_spec_decl_friend : Error< "cannot declare an explicit specialization in a friend">; def err_template_spec_decl_out_of_scope_global : Error< - "%select{class template|class template partial|function template|member " - "function|static data member|member class|member enumeration}0 " + "%select{class template|class template partial|variable template|" + "variable template partial|function template|member function|" + "static data member|member class|member enumeration}0 " "specialization of %1 must originally be declared in the global scope">; def err_template_spec_decl_out_of_scope : Error< - "%select{class template|class template partial|function template|member " + "%select{class template|class template partial|variable template|" + "variable template partial|function template|member " "function|static data member|member class|member enumeration}0 " "specialization of %1 must originally be declared in namespace %2">; def ext_template_spec_decl_out_of_scope : ExtWarn< "first declaration of %select{class template|class template partial|" + "variable template|variable template partial|" "function template|member function|static data member|member class|" "member enumeration}0 specialization of %1 outside namespace %2 is a " "C++11 extension">, InGroup<CXX11>; def warn_cxx98_compat_template_spec_decl_out_of_scope : Warning< - "%select{class template|class template partial|function template|member " + "%select{class template|class template partial|variable template|" + "variable template partial|function template|member " "function|static data member|member class|member enumeration}0 " "specialization of %1 outside namespace %2 is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; def err_template_spec_redecl_out_of_scope : Error< - "%select{class template|class template partial|function template|member " + "%select{class template|class template partial|variable template|" + "variable template partial|function template|member " "function|static data member|member class|member enumeration}0 " "specialization of %1 not in a namespace enclosing %2">; def err_template_spec_redecl_global_scope : Error< - "%select{class template|class template partial|function template|member " + "%select{class template|class template partial|variable template|" + "variable template partial|function template|member " "function|static data member|member class|member enumeration}0 " "specialization of %1 must occur at global scope">; def err_spec_member_not_instantiated : Error< @@ -3029,12 +3168,12 @@ def err_dependent_typed_non_type_arg_in_partial_spec : Error< "non-type template argument specializes a template parameter with " "dependent type %0">; def err_partial_spec_args_match_primary_template : Error< - "class template partial specialization does not specialize any template " - "argument; to %select{declare|define}0 the primary template, remove the " - "template argument list">; + "%select{class|variable}0 template partial specialization does not " + "specialize any template argument; to %select{declare|define}1 the " + "primary template, remove the template argument list">; def warn_partial_specs_not_deducible : Warning< - "class template partial specialization contains " - "%select{a template parameter|template parameters}0 that can not be " + "%select{class|variable}0 template partial specialization contains " + "%select{a template parameter|template parameters}1 that can not be " "deduced; this partial specialization will never be used">; def note_partial_spec_unused_parameter : Note< "non-deducible template parameter %0">; @@ -3047,6 +3186,14 @@ def note_prev_partial_spec_here : Note< "previous declaration of class template partial specialization %0 is here">; def err_partial_spec_fully_specialized : Error< "partial specialization of %0 does not use any of its template parameters">; + +// C++ Variable Template Partial Specialization +def err_var_partial_spec_redeclared : Error< + "variable template partial specialization %0 cannot be redefined">; +def note_var_prev_partial_spec_here : Note< + "previous declaration of variable template partial specialization is here">; +def err_var_spec_no_template : Error< + "no variable template matches%select{| partial}0 specialization">; // C++ Function template specializations def err_function_template_spec_no_match : Error< @@ -3084,6 +3231,8 @@ def note_function_template_spec_here : Note< "in instantiation of function template specialization %q0 requested here">; def note_template_static_data_member_def_here : Note< "in instantiation of static data member %q0 requested here">; +def note_template_variable_def_here : Note< + "in instantiation of variable template specialization %q0 requested here">; def note_template_enum_def_here : Note< "in instantiation of enumeration %q0 requested here">; def note_template_type_alias_instantiation_here : Note< @@ -3160,8 +3309,8 @@ def err_explicit_instantiation_of_typedef : Error< def err_explicit_instantiation_storage_class : Error< "explicit instantiation cannot have a storage class">; def err_explicit_instantiation_not_known : Error< - "explicit instantiation of %0 does not refer to a function template, member " - "function, member class, or static data member">; + "explicit instantiation of %0 does not refer to a function template, " + "variable template, member function, member class, or static data member">; def note_explicit_instantiation_here : Note< "explicit instantiation refers here">; def err_explicit_instantiation_data_member_not_instantiated : Error< @@ -3184,6 +3333,8 @@ def err_explicit_instantiation_constexpr : Error< def ext_explicit_instantiation_without_qualified_id : Extension< "qualifier in explicit instantiation of %q0 requires a template-id " "(a typedef is not permitted)">; +def err_explicit_instantiation_without_template_id : Error< + "explicit instantiation of %q0 must specify a template argument list">; def err_explicit_instantiation_unqualified_wrong_namespace : Error< "explicit instantiation of %q0 must occur in namespace %1">; def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning< @@ -3194,11 +3345,17 @@ def err_explicit_instantiation_undefined_member : Error< "static data member}0 %1 of class template %2">; def err_explicit_instantiation_undefined_func_template : Error< "explicit instantiation of undefined function template %0">; +def err_explicit_instantiation_undefined_var_template : Error< + "explicit instantiation of undefined variable template %q0">; def err_explicit_instantiation_declaration_after_definition : Error< "explicit instantiation declaration (with 'extern') follows explicit " "instantiation definition (without 'extern')">; def note_explicit_instantiation_definition_here : Note< "explicit instantiation definition is here">; +def err_invalid_var_template_spec_type : Error<"type %2 " + "of %select{explicit instantiation|explicit specialization|" + "partial specialization|redeclaration}0 of %1 does not match" + " expected type %3">; // C++ typename-specifiers def err_typename_nested_not_found : Error<"no type named %0 in %1">; @@ -3244,7 +3401,8 @@ def err_non_type_template_in_nested_name_specifier : Error< def err_template_id_not_a_type : Error< "template name refers to non-type template %0">; def note_template_declared_here : Note< - "%select{function template|class template|type alias template|template template parameter}0 " + "%select{function template|class template|variable template" + "|type alias template|template template parameter}0 " "%1 declared here">; def note_parameter_type : Note< "parameter of type %0 is declared here">; @@ -3350,6 +3508,10 @@ def note_unavailable_here : Note< "%select{unavailable|deleted|deprecated}1 here">; def note_implicitly_deleted : Note< "explicitly defaulted function was implicitly deleted here">; +def note_inherited_deleted_here : Note< + "deleted constructor was inherited here">; +def note_cannot_inherit : Note< + "constructor cannot be inherited">; def warn_not_enough_argument : Warning< "not enough variable arguments in %0 declaration to fit a sentinel">, InGroup<Sentinel>; @@ -3367,10 +3529,14 @@ def warn_missing_variable_declarations : Warning< "no previous extern declaration for non-static variable %0">, InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore; def err_redefinition : Error<"redefinition of %0">; +def err_alias_after_tentative : + Error<"alias definition of %0 after tentative definition">; +def err_tentative_after_alias : + Error<"tentative definition of %0 after alias definition">; def err_definition_of_implicitly_declared_member : Error< "definition of implicitly declared %select{default constructor|copy " "constructor|move constructor|copy assignment operator|move assignment " - "operator|destructor}1">; + "operator|destructor|function}1">; def err_definition_of_explicitly_defaulted_member : Error< "definition of explicitly defaulted %select{default constructor|copy " "constructor|move constructor|copy assignment operator|move assignment " @@ -3444,6 +3610,14 @@ def err_static_non_static : Error< "static declaration of %0 follows non-static declaration">; def err_different_language_linkage : Error< "declaration of %0 has a different language linkage">; +def ext_retained_language_linkage : Extension< + "friend function %0 retaining previous language linkage is an extension">, + InGroup<DiagGroup<"retained-language-linkage">>; +def err_extern_c_global_conflict : Error< + "declaration of %1 %select{with C language linkage|in global scope}0 " + "conflicts with declaration %select{in global scope|with C language linkage}0">; +def note_extern_c_global_conflict : Note< + "declared %select{in global scope|with C language linkage}0 here">; def warn_weak_import : Warning < "an already-declared variable is made a weak_import declaration %0">; def warn_static_non_static : ExtWarn< @@ -3503,7 +3677,7 @@ def err_forward_ref_enum : Error< def ext_ms_forward_ref_enum : Extension< "forward references to 'enum' types are a Microsoft extension">, InGroup<Microsoft>; def ext_forward_ref_enum_def : Extension< - "redeclaration of already-defined enum %0 is a GNU extension">, InGroup<GNU>; + "redeclaration of already-defined enum %0 is a GNU extension">, InGroup<GNURedeclaredEnum>; def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">; def err_duplicate_member : Error<"duplicate member %0">; @@ -3574,6 +3748,8 @@ def warn_typecheck_zero_static_array_size : Warning< def err_array_size_non_int : Error<"size of array has non-integer type %0">; def err_init_element_not_constant : Error< "initializer element is not a compile-time constant">; +def ext_aggregate_init_not_constant : Extension< + "initializer for aggregate is not a compile-time constant">, InGroup<C99>; def err_local_cant_init : Error< "'__local' variable cannot have an initializer">; def err_block_extern_cant_init : Error< @@ -3620,22 +3796,15 @@ def warn_cxx98_compat_ctor_list_init : Warning< def err_illegal_initializer : Error< "illegal initializer (only variables can be initialized)">; def err_illegal_initializer_type : Error<"illegal initializer type %0">; -def err_init_list_type_narrowing_sfinae : Error< - "type %0 cannot be narrowed to %1 in initializer list">; -def err_init_list_type_narrowing : ExtWarn< +def ext_init_list_type_narrowing : ExtWarn< "type %0 cannot be narrowed to %1 in initializer list">, - InGroup<CXX11Narrowing>, DefaultError; -def err_init_list_variable_narrowing_sfinae : Error< - "non-constant-expression cannot be narrowed from type %0 to %1 in " - "initializer list">; -def err_init_list_variable_narrowing : ExtWarn< + InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure; +def ext_init_list_variable_narrowing : ExtWarn< "non-constant-expression cannot be narrowed from type %0 to %1 in " - "initializer list">, InGroup<CXX11Narrowing>, DefaultError; -def err_init_list_constant_narrowing_sfinae : Error< - "constant expression evaluates to %0 which cannot be narrowed to type %1">; -def err_init_list_constant_narrowing : ExtWarn< + "initializer list">, InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure; +def ext_init_list_constant_narrowing : ExtWarn< "constant expression evaluates to %0 which cannot be narrowed to type %1">, - InGroup<CXX11Narrowing>, DefaultError; + InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure; def warn_init_list_type_narrowing : Warning< "type %0 cannot be narrowed to %1 in initializer list in C++11">, InGroup<CXX11Narrowing>, DefaultIgnore; @@ -3676,9 +3845,6 @@ def warn_anon_bitfield_width_exceeds_type_size : Warning< def warn_missing_braces : Warning< "suggest braces around initialization of subobject">, InGroup<MissingBraces>, DefaultIgnore; -def err_missing_braces : Error< - "cannot omit braces around initialization of subobject when using direct " - "list-initialization">; def err_redefinition_of_label : Error<"redefinition of label %0">; def err_undeclared_label_use : Error<"use of undeclared label %0">; @@ -3778,10 +3944,16 @@ def err_field_declared_as_function : Error<"field %0 declared as a function">; def err_field_incomplete : Error<"field has incomplete type %0">; def ext_variable_sized_type_in_struct : ExtWarn< "field %0 with variable sized type %1 not at the end of a struct or class is" - " a GNU extension">, InGroup<GNU>; - -def err_flexible_array_empty_struct : Error< - "flexible array %0 not allowed in otherwise empty struct">; + " a GNU extension">, InGroup<GNUVariableSizedTypeNotAtEnd>; + +def ext_c99_flexible_array_member : Extension< + "flexible array members are a C99 feature">, InGroup<C99>; +def err_flexible_array_virtual_base : Error< + "flexible array member %0 not allowed in " + "%select{struct|interface|union|class|enum}1 which has a virtual base class">; +def err_flexible_array_empty_aggregate : Error< + "flexible array member %0 not allowed in otherwise empty " + "%select{struct|interface|union|class|enum}1">; def err_flexible_array_has_nonpod_type : Error< "flexible array member %0 of non-POD element type %1">; def ext_flexible_array_in_struct : Extension< @@ -3796,15 +3968,17 @@ def ext_flexible_array_empty_aggregate_ms : Extension< "flexible array member %0 in otherwise empty " "%select{struct|interface|union|class|enum}1 is a Microsoft extension">, InGroup<Microsoft>; +def err_flexible_array_union : Error< + "flexible array member %0 in a union is not allowed">; 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|interface|union|class|enum}1 is a GNU extension">, - InGroup<GNU>; + InGroup<GNUEmptyStruct>; def ext_flexible_array_union_gnu : Extension< - "flexible array member %0 in a union is a GNU extension">, InGroup<GNU>; + "flexible array member %0 in a union is a GNU extension">, InGroup<GNUFlexibleArrayUnionMember>; let CategoryName = "ARC Semantic Issue" in { @@ -3852,7 +4026,7 @@ def err_arc_objc_property_default_assign_on_object : Error< 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">; + "ARC forbids %select{implementation|synthesis}0 of %1">; def warn_arc_strong_pointer_objc_pointer : Warning< "method parameter of type %0 with no explicit ownership">, InGroup<DiagGroup<"explicit-ownership-type">>, DefaultIgnore; @@ -4053,6 +4227,9 @@ def ext_sizeof_alignof_void_type : Extension< def err_sizeof_alignof_incomplete_type : Error< "invalid application of '%select{sizeof|alignof|vec_step}0' to an " "incomplete type %1">; +def err_sizeof_alignof_function_type : Error< + "invalid application of '%select{sizeof|alignof|vec_step}0' to a " + "function type">; def err_sizeof_alignof_bitfield : Error< "invalid application of '%select{sizeof|alignof}0' to bit-field">; def err_alignof_member_of_incomplete_type : Error< @@ -4072,6 +4249,11 @@ def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">, def warn_offsetof_non_standardlayout_type : ExtWarn< "offset of on non-standard-layout type %0">, InGroup<InvalidOffsetof>; def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">; +def err_offsetof_field_of_virtual_base : Error< + "invalid application of 'offsetof' to a field of a virtual base">; +def warn_sub_ptr_zero_size_types : Warning< + "subtraction of pointers to type %0 of zero size has undefined behavior">, + InGroup<PointerArith>; def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, @@ -4139,7 +4321,10 @@ def warn_self_assignment : Warning< def warn_string_plus_int : Warning< "adding %0 to a string does not append to the string">, InGroup<StringPlusInt>; -def note_string_plus_int_silence : Note< +def warn_string_plus_char : Warning< + "adding %0 to a string pointer does not append to the string">, + InGroup<StringPlusChar>; +def note_string_plus_scalar_silence : Note< "use array indexing to silence this warning">; def warn_sizeof_array_param : Warning< @@ -4189,6 +4374,10 @@ def err_typecheck_member_reference_arrow : Error< "member reference type %0 is not a pointer">; def err_typecheck_member_reference_suggestion : Error< "member reference type %0 is %select{a|not a}1 pointer; maybe you meant to use '%select{->|.}1'?">; +def note_typecheck_member_reference_suggestion : Note< + "did you mean to use '.' instead?">; +def note_member_reference_arrow_from_operator_arrow : Note< + "'->' applied to return value of the operator->() declared here">; def err_typecheck_member_reference_type : Error< "cannot refer to type member %0 in %1 with '%select{.|->}2'">; def err_typecheck_member_reference_unknown : Error< @@ -4215,20 +4404,28 @@ def note_enum_specialized_here : Note< "enum %0 was explicitly specialized here">; def err_member_redeclared : Error<"class member cannot be redeclared">; +def ext_member_redeclared : ExtWarn<"class member cannot be redeclared">, + InGroup<RedeclaredClassMember>; def err_member_redeclared_in_instantiation : Error< "multiple overloads of %0 instantiate to the same signature %1">; def err_member_name_of_class : Error<"member %0 has the same name as its class">; def err_member_def_undefined_record : Error< "out-of-line definition of %0 from class %1 without definition">; -def err_member_def_does_not_match : Error< - "out-of-line definition of %0 does not match any declaration in %1">; +def err_member_decl_does_not_match : Error< + "out-of-line %select{declaration|definition}2 of %0 " + "does not match any declaration in %1">; +def err_friend_decl_with_def_arg_must_be_def : Error< + "friend declaration specifying a default argument must be a definition">; +def err_friend_decl_with_def_arg_redeclared : Error< + "friend declaration specifying a default argument must be the only declaration">; def err_friend_decl_does_not_match : Error< "friend declaration of %0 does not match any declaration in %1">; -def err_member_def_does_not_match_suggest : Error< - "out-of-line definition of %0 does not match any declaration in %1; " - "did you mean %2?">; +def err_member_decl_does_not_match_suggest : Error< + "out-of-line %select{declaration|definition}2 of %0 " + "does not match any declaration in %1; did you mean %3?">; def err_member_def_does_not_match_ret_type : Error< - "out-of-line definition of %q0 differs from the declaration in the return type">; + "return type of out-of-line definition of %q0 differs from " + "that in the declaration">; def err_nonstatic_member_out_of_line : Error< "non-static data member defined out-of-line">; def err_qualified_typedef_declarator : Error< @@ -4251,6 +4448,10 @@ def note_member_def_close_const_match : Note< def note_member_def_close_param_match : Note< "type of %ordinal0 parameter of member declaration does not match definition" "%diff{ ($ vs $)|}1,2">; +def note_local_decl_close_match : Note<"local declaration nearly matches">; +def note_local_decl_close_param_match : Note< + "type of %ordinal0 parameter of local declaration does not match definition" + "%diff{ ($ vs $)|}1,2">; def err_typecheck_ivar_variable_size : Error< "instance variables must have a constant size">; def err_ivar_reference_type : Error< @@ -4266,13 +4467,13 @@ def err_typecheck_pointer_arith_void_type : Error< "arithmetic on%select{ a|}0 pointer%select{|s}0 to void">; def err_typecheck_decl_incomplete_type : Error< "variable has incomplete type %0">; +def err_typecheck_decl_incomplete_type___float128 : Error< + "support for type '__float128' is not yet implemented">; def ext_typecheck_decl_incomplete_type : ExtWarn< "tentative definition of variable with internal linkage has incomplete non-array type %0">, InGroup<DiagGroup<"tentative-definition-incomplete-type">>; def err_tentative_def_incomplete_type : Error< "tentative definition has type %0 that is never completed">; -def err_tentative_def_incomplete_type_arr : Error< - "tentative definition has array of type %0 that is never completed">; def warn_tentative_incomplete_array : Warning< "tentative array definition assumed to have one element">; def err_typecheck_incomplete_array_needs_initializer : Error< @@ -4280,7 +4481,13 @@ def err_typecheck_incomplete_array_needs_initializer : Error< "or an initializer">; def err_array_init_not_init_list : Error< "array initializer must be an initializer " - "list%select{| or string literal}0">; + "list%select{| or string literal| or wide string literal}0">; +def err_array_init_narrow_string_into_wchar : Error< + "initializing wide char array with non-wide string literal">; +def err_array_init_wide_string_into_char : Error< + "initializing char array with wide string literal">; +def err_array_init_incompat_wide_string_into_wchar : Error< + "initializing wide char array with incompatible wide string literal">; def err_array_init_different_type : Error< "cannot initialize array %diff{of type $ with array of type $|" "with different type of array}0,1">; @@ -4290,13 +4497,16 @@ def err_array_init_non_constant_array : Error< def ext_array_init_copy : Extension< "initialization of an array " "%diff{of type $ from a compound literal of type $|" - "from a compound literal}0,1 is a GNU extension">, InGroup<GNU>; + "from a compound literal}0,1 is a GNU extension">, InGroup<GNUCompoundLiteralInitializer>; // This is intentionally not disabled by -Wno-gnu. def ext_array_init_parens : ExtWarn< "parenthesized initialization of a member array is a GNU extension">, InGroup<DiagGroup<"gnu-array-member-paren-init">>, DefaultError; def warn_deprecated_string_literal_conversion : Warning< - "conversion from string literal to %0 is deprecated">, InGroup<DeprecatedWritableStr>; + "conversion from string literal to %0 is deprecated">, + InGroup<CXX11CompatDeprecatedWritableStr>; +def warn_deprecated_string_literal_conversion_c : Warning< + "dummy warning to enable -fconst-strings">, InGroup<DeprecatedWritableStr>, DefaultIgnore; def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">; def err_typecheck_sclass_fscope : Error< "illegal storage class on file-scoped variable">; @@ -4331,6 +4541,8 @@ def ext_typecheck_addrof_temporary : ExtWarn< InGroup<DiagGroup<"address-of-temporary">>, DefaultError; def err_typecheck_addrof_temporary : Error< "taking the address of a temporary object of type %0">; +def err_typecheck_addrof_dtor : Error< + "taking the address of a destructor">; def err_typecheck_unary_expr : Error< "invalid argument type %0 to unary expression">; def err_typecheck_indirection_requires_pointer : Error< @@ -4405,6 +4617,14 @@ def warn_null_in_comparison_operation : Warning< "%select{(%1 and NULL)|(NULL and %1)}0">, InGroup<NullArithmetic>; +def warn_logical_not_on_lhs_of_comparison : Warning< + "logical not is only applied to the left hand side of this comparison">, + InGroup<LogicalNotParentheses>; +def note_logical_not_fix : Note< + "add parentheses after the '!' to evaluate the comparison first">; +def note_logical_not_silence_with_parens : Note< + "add parentheses around left hand side expression to silence this warning">; + def err_invalid_this_use : Error< "invalid use of 'this' outside of a non-static member function">; def err_this_static_member_func : Error< @@ -4547,6 +4767,15 @@ def warn_instance_method_on_class_found : Warning< def warn_inst_method_not_found : Warning< "instance method %objcinstance0 not found (return type defaults to 'id')">, InGroup<MethodAccess>; +def warn_instance_method_not_found_with_typo : Warning< + "instance method %objcinstance0 not found (return type defaults to 'id')" + "; did you mean %objcinstance2?">, InGroup<MethodAccess>; +def warn_class_method_not_found_with_typo : Warning< + "class method %objcclass0 not found (return type defaults to 'id')" + "; did you mean %objcclass2?">, InGroup<MethodAccess>; +def error_method_not_found_with_typo : Error< + "%select{instance|class}1 method %0 not found " + "; did you mean %2?">; def error_no_super_class_message : Error< "no @interface declaration found in class messaging of %0">; def error_root_class_cannot_use_super : Error< @@ -4561,6 +4790,7 @@ def warn_bad_receiver_type : Warning< "receiver type %0 is not 'id' or interface pointer, consider " "casting it to 'id'">,InGroup<ObjCReceiver>; def err_bad_receiver_type : Error<"bad receiver type %0">; +def err_incomplete_receiver_type : Error<"incomplete receiver type %0">; def err_unknown_receiver_suggest : Error< "unknown receiver %0; did you mean %1?">; def error_objc_throw_expects_object : Error< @@ -4602,6 +4832,8 @@ def note_parameter_named_here : Note< "passing argument to parameter %0 here">; def note_parameter_here : Note< "passing argument to parameter here">; +def note_method_return_type_change : Note< + "compiler has implicitly changed method %0 return type">; // C++ casts // These messages adhere to the TryCast pattern: %0 is an int specifying the @@ -4695,6 +4927,8 @@ def err_need_header_before_ms_uuidof : Error< "you need to include <guiddef.h> before using the '__uuidof' operator">; def err_uuidof_without_guid : Error< "cannot call operator __uuidof on a type with no GUID">; +def err_uuidof_with_multiple_guids : Error< + "cannot call operator __uuidof on a type with multiple GUIDs">; def err_incomplete_typeid : Error<"'typeid' of incomplete type %0">; def err_static_illegal_in_new : Error< "the 'static' modifier for the array size is not legal in new expressions">; @@ -4744,13 +4978,17 @@ def err_default_init_const : Error< def err_delete_operand : Error<"cannot delete expression of type %0">; def ext_delete_void_ptr_operand : ExtWarn< "cannot delete expression with pointer-to-'void' type %0">; -def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete " - "expression of type %0 to a pointer">; +def err_ambiguous_delete_operand : Error< + "ambiguous conversion of delete expression of type %0 to a pointer">; def warn_delete_incomplete : Warning< "deleting pointer to incomplete type %0 may cause undefined behavior">, InGroup<DiagGroup<"delete-incomplete">>; def err_delete_incomplete_class_type : Error< "deleting incomplete class type %0; no conversions to pointer type">; +def err_delete_explicit_conversion : Error< + "converting delete expression from type %0 to type %1 invokes an explicit " + "conversion function">; +def note_delete_conversion : Note<"conversion to pointer type %0">; def warn_delete_array_type : Warning< "'delete' applied to a pointer-to-array type %0 treated as delete[]">; def err_no_suitable_delete_member_function_found : Error< @@ -4761,7 +4999,10 @@ def note_member_declared_here : Note< "member %0 declared here">; def err_decrement_bool : Error<"cannot decrement expression of type bool">; def warn_increment_bool : Warning< - "incrementing expression of type bool is deprecated">, InGroup<Deprecated>; + "incrementing expression of type bool is deprecated">, + InGroup<DeprecatedIncrementBool>; +def err_increment_decrement_enum : Error< + "cannot %select{decrement|increment}0 expression of enum type %1">; def err_catch_incomplete_ptr : Error< "cannot catch pointer to incomplete type %0">; def err_catch_incomplete_ref : Error< @@ -4848,8 +5089,6 @@ let CategoryName = "Lambda Issue" in { "duration">; def err_this_capture : Error< "'this' cannot be %select{implicitly |}0captured in this context">; - def err_lambda_capture_block : Error< - "__block variable %0 cannot be captured in a lambda expression">; def err_lambda_capture_anonymous_var : Error< "unnamed variable cannot be implicitly captured in a lambda expression">; def err_lambda_capture_vm_type : Error< @@ -4864,14 +5103,14 @@ let CategoryName = "Lambda Issue" in { def note_lambda_decl : Note<"lambda expression begins here">; def err_lambda_unevaluated_operand : Error< "lambda expression in an unevaluated operand">; + def err_lambda_in_constant_expression : Error< + "a lambda expression may not appear inside of a constant expression">; def err_lambda_return_init_list : Error< "cannot deduce lambda return type from initializer list">; def err_lambda_capture_default_arg : Error< "lambda expression in default argument cannot capture any entity">; def err_lambda_incomplete_result : Error< "incomplete result type %0 in lambda expression">; - def err_lambda_objc_object_result : Error< - "non-pointer Objective-C class type %0 in lambda expression result">; def err_noreturn_lambda_has_return_expr : Error< "lambda declared 'noreturn' should not return">; def warn_maybe_falloff_nonvoid_lambda : Warning< @@ -4889,13 +5128,41 @@ let CategoryName = "Lambda Issue" in { def note_lambda_to_block_conv : Note< "implicit capture of lambda object due to conversion to block pointer " "here">; + + // C++1y lambda init-captures. + def warn_cxx11_compat_init_capture : Warning< + "initialized lambda captures are incompatible with C++ standards " + "before C++1y">, InGroup<CXXPre1yCompat>, DefaultIgnore; + def ext_init_capture : ExtWarn< + "initialized lambda captures are a C++1y extension">, InGroup<CXX1y>; + def err_init_capture_no_expression : Error< + "initializer missing for lambda capture %0">; + def err_init_capture_multiple_expressions : Error< + "initializer for lambda capture %0 contains multiple expressions">; + def err_init_capture_deduction_failure : Error< + "cannot deduce type for lambda capture %0 from initializer of type %2">; + def err_init_capture_deduction_failure_from_init_list : Error< + "cannot deduce type for lambda capture %0 from initializer list">; } def err_return_in_captured_stmt : Error< "cannot return from %0">; +def err_capture_block_variable : Error< + "__block variable %0 cannot be captured in a " + "%select{lambda expression|captured statement}1">; def err_operator_arrow_circular : Error< "circular pointer delegation detected">; +def err_operator_arrow_depth_exceeded : Error< + "use of 'operator->' on type %0 would invoke a sequence of more than %1 " + "'operator->' calls">; +def note_operator_arrow_here : Note< + "'operator->' declared here produces an object of type %0">; +def note_operator_arrows_suppressed : Note< + "(skipping %0 'operator->'%s0 in backtrace)">; +def note_operator_arrow_depth : Note< + "use -foperator-arrow-depth=N to increase 'operator->' limit">; + def err_pseudo_dtor_base_not_scalar : Error< "object expression of non-scalar type %0 cannot be used in a " "pseudo-destructor expression">; @@ -4926,6 +5193,8 @@ def err_typecheck_ambiguous_condition : Error< "conversion %diff{from $ to $|between types}0,1 is ambiguous">; def err_typecheck_nonviable_condition : Error< "no viable conversion%diff{ from $ to $|}0,1">; +def err_typecheck_nonviable_condition_incomplete : Error< + "no viable conversion%diff{ from $ to incomplete type $|}0,1">; def err_typecheck_deleted_function : Error< "conversion function %diff{from $ to $|between types}0,1 " "invokes a deleted function">; @@ -4939,11 +5208,15 @@ def err_invalid_declarator_global_scope : Error< "definition or redeclaration of %0 cannot name the global scope">; def err_invalid_declarator_in_function : Error< "definition or redeclaration of %0 not allowed inside a function">; +def err_invalid_declarator_in_block : Error< + "definition or redeclaration of %0 not allowed inside a block">; def err_not_tag_in_scope : Error< "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">; +def err_no_dynamic_cast_with_fno_rtti : Error< + "cannot use dynamic_cast with -fno-rtti">; def err_cannot_form_pointer_to_member_of_reference_type : Error< "cannot form a pointer-to-member to member %0 of reference type %1">; @@ -5243,6 +5516,14 @@ def err_typecheck_call_too_few_args_at_least_one : Error< "too few %select{|||execution configuration }0arguments to " "%select{function|block|method|kernel function}0 call, " "at least argument %1 must be specified">; +def err_typecheck_call_too_few_args_suggest : Error< + "too few %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " + "expected %1, have %2; did you mean %3?">; +def err_typecheck_call_too_few_args_at_least_suggest : Error< + "too few %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " + "expected at least %1, have %2; did you mean %3?">; def err_typecheck_call_too_many_args : Error< "too many %select{|||execution configuration }0arguments to " "%select{function|block|method|kernel function}0 call, " @@ -5259,6 +5540,19 @@ def err_typecheck_call_too_many_args_at_most_one : Error< "too many %select{|||execution configuration }0arguments to " "%select{function|block|method|kernel function}0 call, " "expected at most single argument %1, have %2 arguments">; +def err_typecheck_call_too_many_args_suggest : Error< + "too many %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " + "expected %1, have %2; did you mean %3?">; +def err_typecheck_call_too_many_args_at_most_suggest : Error< + "too many %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " + "expected at most %1, have %2; did you mean %3?">; + +def err_arc_typecheck_convert_incompatible_pointer : Error< + "incompatible pointer types passing retainable parameter of type %0" + "to a CF function expecting %1 type">; + def note_callee_decl : Note< "%0 declared here">; def note_defined_here : Note<"%0 defined here">; @@ -5268,28 +5562,38 @@ 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< - "first argument to atomic builtin must be a pointer (%0 invalid)">; + "address argument to atomic builtin must be a pointer (%0 invalid)">; def err_atomic_builtin_must_be_pointer_intptr : Error< - "first argument to atomic builtin must be a pointer to integer or pointer" + "address argument to atomic builtin must be a pointer to integer or pointer" " (%0 invalid)">; +def err_atomic_builtin_must_be_pointer_intfltptr : Error< + "address argument to atomic builtin must be a pointer to integer," + " floating-point or pointer (%0 invalid)">; def err_atomic_builtin_pointer_size : Error< - "first argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte " + "address argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte " "type (%0 invalid)">; +def err_atomic_exclusive_builtin_pointer_size : Error< + "address argument to load or store exclusive builtin must be a pointer to" + " 1,2,4 or 8 byte type (%0 invalid)">; def err_atomic_op_needs_atomic : Error< - "first argument to atomic operation must be a pointer to _Atomic " + "address 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 " + "address 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)">; + "address argument to atomic operation must be a pointer to a " + "trivially-copyable type (%0 invalid)">; def err_atomic_op_needs_atomic_int_or_ptr : Error< - "first argument to atomic operation must be a pointer to %select{|atomic }0" + "address argument to atomic operation must be a pointer to %select{|atomic }0" "integer or pointer (%1 invalid)">; def err_atomic_op_bitwise_needs_atomic_int : Error< - "first argument to bitwise atomic operation must be a pointer to " + "address argument to bitwise atomic operation must be a pointer to " "%select{|atomic }0integer (%1 invalid)">; + +def err_atomic_load_store_uses_lib : Error< + "atomic %select{load|store}0 requires runtime support that is not " + "available for this target">; def err_deleted_function_use : Error<"attempt to use a deleted function">; @@ -5326,6 +5630,13 @@ def warn_cxx98_compat_pass_non_pod_arg_to_vararg : Warning< "passing object of trivial but non-POD type %0 through variadic" " %select{function|block|method|constructor}1 is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; +def err_cannot_pass_to_vararg : Error< + "cannot pass %select{expression of type %1|initializer list}0 to variadic " + "%select{function|block|method|constructor}2">; +def err_cannot_pass_to_vararg_format : Error< + "cannot pass %select{expression of type %1|initializer list}0 to variadic " + "%select{function|block|method|constructor}2; expected type from format " + "string was %3">; def err_typecheck_call_invalid_ordered_compare : Error< "ordered compare requires two args of floating point type" @@ -5345,7 +5656,7 @@ def ext_typecheck_cast_nonscalar : Extension< "C99 forbids casting nonscalar type %0 to the same type">; def ext_typecheck_cast_to_union : Extension< "cast to union type is a GNU extension">, - InGroup<GNU>; + InGroup<GNUUnionCast>; 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< @@ -5415,6 +5726,16 @@ def err_expected_ident_or_lparen : Error<"expected identifier or '('">; def err_typecheck_cond_incompatible_operands_null : Error< "non-pointer operand type %0 incompatible with %select{NULL|nullptr}1">; +def ext_empty_struct_union : Extension< + "empty %select{struct|union}0 is a GNU extension">, InGroup<GNUEmptyStruct>; +def ext_no_named_members_in_struct_union : Extension< + "%select{struct|union}0 without named members is a GNU extension">, InGroup<GNUEmptyStruct>; +def warn_zero_size_struct_union_compat : Warning<"%select{|empty }0" + "%select{struct|union}1 has size 0 in C, %select{size 1|non-zero size}2 in C++">, + InGroup<CXXCompat>, DefaultIgnore; +def warn_zero_size_struct_union_in_extern_c : Warning<"%select{|empty }0" + "%select{struct|union}1 has size 0 in C, %select{size 1|non-zero size}2 in C++">, + InGroup<ExternCCompat>; } // End of general sema category. // inline asm. @@ -5447,8 +5768,8 @@ let CategoryName = "Inline Assembly Issue" in { "accepted due to -fheinous-gnu-extensions, but clang may remove support " "for this in the future">; def warn_asm_mismatched_size_modifier : Warning< - "the value is truncated when put into register, " - "use a modifier to specify the size">, + "value size does not match register size specified by the constraint " + "and modifier">, InGroup<ASMOperandWidths>; } @@ -5483,6 +5804,10 @@ def warn_initializer_out_of_order : Warning< "%select{field|base class}0 %1 will be initialized after " "%select{field|base}2 %3">, InGroup<Reorder>, DefaultIgnore; +def warn_abstract_vbase_init_ignored : Warning< + "initializer for virtual base class %0 of abstract class %1 " + "will never be used">, + InGroup<DiagGroup<"abstract-vbase-init">>, DefaultIgnore; def err_base_init_does_not_name_class : Error< "constructor initializer %0 does not name a class">; @@ -5516,7 +5841,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">, InGroup<GNU>; + "folding it to a constant is a GNU extension">, InGroup<GNUFoldingConstant>; def err_thread_dynamic_init : Error< "initializer for thread-local variable must be a constant expression">; @@ -5529,7 +5854,7 @@ def note_use_thread_local : Note< def ext_anonymous_union : Extension< "anonymous unions are a C11 extension">, InGroup<C11>; def ext_gnu_anonymous_struct : Extension< - "anonymous structs are a GNU extension">, InGroup<GNU>; + "anonymous structs are a GNU extension">, InGroup<GNUAnonymousStruct>; def ext_c11_anonymous_struct : Extension< "anonymous structs are a C11 extension">, InGroup<C11>; def err_anonymous_union_not_static : Error< @@ -5584,6 +5909,8 @@ 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_base_class_has_flexible_array_member : Error< + "base class %0 has a flexible array member">; 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">; @@ -5636,6 +5963,9 @@ def err_operator_new_delete_declared_in_namespace : Error< "%0 cannot be declared inside a namespace">; def err_operator_new_delete_declared_static : Error< "%0 cannot be declared static in global scope">; +def ext_operator_new_delete_declared_inline : ExtWarn< + "replacement function %0 cannot be declared 'inline'">, + InGroup<DiagGroup<"inline-new-delete">>; def err_operator_new_delete_invalid_result_type : Error< "%0 must return type %1">; def err_operator_new_delete_dependent_result_type : Error< @@ -5667,9 +5997,12 @@ def err_literal_operator_params : Error< "parameter declaration for literal operator %0 is not valid">; def err_literal_operator_extern_c : Error< "literal operator must have C++ linkage">; +def ext_string_literal_operator_template : ExtWarn< + "string literal operator templates are a GNU extension">, + InGroup<GNUStringLiteralOperatorTemplate>; def warn_user_literal_reserved : Warning< - "user-defined literal suffixes not starting with '_' are reserved; " - "no literal will invoke this operator">, + "user-defined literal suffixes not starting with '_' are reserved" + "%select{; no literal will invoke this operator|}0">, InGroup<UserDefinedLiterals>; // C++ conversion functions @@ -5718,7 +6051,7 @@ def err_defaulted_special_member_return_type : Error< "return %1">; def err_defaulted_special_member_quals : Error< "an explicitly-defaulted %select{copy|move}0 assignment operator may not " - "have 'const', 'constexpr' or 'volatile' qualifiers">; + "have 'const'%select{, 'constexpr'|}1 or 'volatile' qualifiers">; def err_defaulted_special_member_volatile_param : Error< "the parameter for an explicitly-defaulted %select{<<ERROR>>|" "copy constructor|move constructor|copy assignment operator|" @@ -5740,11 +6073,19 @@ def err_incorrect_defaulted_exception_spec : Error< "calculated one">; def err_incorrect_defaulted_constexpr : Error< "defaulted definition of %select{default constructor|copy constructor|" - "move constructor}0 is not constexpr">; + "move constructor|copy assignment operator|move assignment operator}0 " + "is not constexpr">; 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 warn_vbase_moved_multiple_times : Warning< + "defaulted move assignment operator of %0 will move assign virtual base " + "class %1 multiple times">, InGroup<DiagGroup<"multiple-move-vbase">>; +def note_vbase_moved_here : Note< + "%select{%1 is a virtual base class of base class %2 declared here|" + "virtual base class %1 declared here}0">; + 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 " @@ -5876,10 +6217,12 @@ def warn_init_ptr_member_to_parameter_addr : Warning< "initializing pointer member %0 with the stack address of parameter %1">, InGroup<DanglingField>; def warn_bind_ref_member_to_temporary : Warning< - "binding reference member %0 to a temporary value">, + "binding reference %select{|subobject of }1member %0 to a temporary value">, InGroup<DanglingField>; def note_ref_or_ptr_member_declared_here : Note< "%select{reference|pointer}0 member declared here">; +def note_ref_subobject_of_member_declared_here : Note< + "member with reference subobject declared here">; // For non-floating point, expressions of the form x == x or x != x // should result in a warning, since these always evaluate to a constant. @@ -6023,7 +6366,7 @@ def warn_unreachable_default : Warning< InGroup<CoveredSwitchDefault>, DefaultIgnore; def warn_not_in_enum : Warning<"case value not in enumerated type %0">, InGroup<Switch>; -def warn_not_in_enum_assignement : Warning<"integer constant not in range " +def warn_not_in_enum_assignment : Warning<"integer constant not in range " "of enumerated type %0">, InGroup<DiagGroup<"assign-enum">>, DefaultIgnore; def err_typecheck_statement_requires_scalar : Error< "statement requires expression of scalar type (%0 invalid)">; @@ -6057,7 +6400,9 @@ def note_empty_body_on_separate_line : Note< def err_va_start_used_in_non_variadic_function : Error< "'va_start' used in function with fixed args">; def warn_second_parameter_of_va_start_not_last_named_argument : Warning< - "second parameter of 'va_start' not last named argument">; + "second parameter of 'va_start' not last named argument">, InGroup<Varargs>; +def warn_va_start_of_reference_type_is_undefined : Warning< + "'va_start' has undefined behavior with reference types">, InGroup<Varargs>; def err_first_argument_to_va_arg_not_of_type_va_list : Error< "first argument to 'va_arg' is of type %0 and not 'va_list'">; def err_second_parameter_to_va_arg_incomplete: Error< @@ -6072,7 +6417,7 @@ def warn_second_parameter_to_va_arg_ownership_qualified : Warning< InGroup<NonPODVarargs>, DefaultError; def warn_second_parameter_to_va_arg_never_compatible : Warning< "second argument to 'va_arg' is of promotable type %0; this va_arg has " - "undefined behavior because arguments will be promoted to %1">; + "undefined behavior because arguments will be promoted to %1">, InGroup<Varargs>; def warn_return_missing_expr : Warning< "non-void %select{function|method}1 %0 should return a value">, DefaultError, @@ -6124,6 +6469,13 @@ def err_shufflevector_argument_too_large : Error< "index for __builtin_shufflevector must be less than the total number " "of vector elements">; +def err_convertvector_non_vector : Error< + "first argument to __builtin_convertvector must be a vector">; +def err_convertvector_non_vector_type : Error< + "second argument to __builtin_convertvector must be a vector type">; +def err_convertvector_incompatible_vector : Error< + "first two arguments to __builtin_convertvector must have the same number of elements">; + def err_vector_incorrect_num_initializers : Error< "%select{too many|too few}0 elements in vector initialization (expected %1 elements, have %2)">; def err_altivec_empty_initializer : Error<"expected initializer">; @@ -6153,6 +6505,8 @@ def err_selector_element_not_lvalue : Error< "selector element is not a valid lvalue">; def err_selector_element_type : Error< "selector element type %0 is not a valid object">; +def err_selector_element_const_type : Error< + "selector element of type %0 cannot be a constant l-value expression">; def err_collection_expr_type : Error< "the type %0 is not a pointer to a fast-enumerable object">; def warn_collection_expr_type : Warning< @@ -6161,6 +6515,9 @@ def warn_collection_expr_type : Warning< def err_invalid_conversion_between_ext_vectors : Error< "invalid conversion between ext-vector type %0 and %1">; +def warn_duplicate_attribute_exact : Warning< + "attribute %0 is already applied">, InGroup<IgnoredAttributes>; + def warn_duplicate_attribute : Warning< "attribute %0 is already applied with different parameters">, InGroup<IgnoredAttributes>; @@ -6231,19 +6588,19 @@ def warn_direct_ivar_access : Warning<"instance variable %0 is being " // Spell-checking diagnostics def err_unknown_type_or_class_name_suggest : Error< - "unknown %select{type|class}2 name %0; did you mean %1?">; + "unknown %select{type|class}1 name %0; did you mean %2?">; def err_unknown_typename_suggest : Error< "unknown type name %0; did you mean %1?">; def err_unknown_nested_typename_suggest : Error< - "no type named %0 in %1; did you mean %2?">; -def err_no_member_suggest : Error<"no member named %0 in %1; did you mean %2?">; + "no type named %0 in %1; did you mean %select{|simply }2%3?">; +def err_no_member_suggest : Error<"no member named %0 in %1; did you mean %select{|simply }2%3?">; def err_undeclared_use_suggest : Error< "use of undeclared %0; did you mean %1?">; def err_undeclared_var_use_suggest : Error< "use of undeclared identifier %0; did you mean %1?">; def err_no_template_suggest : Error<"no template named %0; did you mean %1?">; def err_no_member_template_suggest : Error< - "no template named %0 in %1; did you mean %2?">; + "no template named %0 in %1; did you mean %select{|simply }2%3?">; def err_mem_init_not_member_or_class_suggest : Error< "initializer %0 does not name a non-static data member or base " "class; did you mean the %select{base class|member}1 %2?">; @@ -6273,7 +6630,7 @@ def note_base_class_specified_here : Note< def err_using_directive_suggest : Error< "no namespace named %0; did you mean %1?">; def err_using_directive_member_suggest : Error< - "no namespace named %0 in %1; did you mean %2?">; + "no namespace named %0 in %1; did you mean %select{|simply }2%3?">; def note_namespace_defined_here : Note<"namespace %0 defined here">; def err_sizeof_pack_no_pack_name_suggest : Error< "%0 does not refer to the name of a parameter pack; did you mean %1?">; @@ -6308,16 +6665,22 @@ def err_invalid_astype_of_different_size : Error< "invalid reinterpretation: sizes of %0 and %1 must match">; def err_static_kernel : Error< "kernel functions cannot be declared static">; -def err_opencl_ptrptr_kernel_arg : Error< - "kernel argument cannot be declared as a pointer to a pointer">; +def err_opencl_ptrptr_kernel_param : Error< + "kernel parameter cannot be declared as a pointer to a pointer">; def err_static_function_scope : Error< "variables in function scope cannot be declared static">; def err_opencl_bitfields : Error< "bitfields are not supported in OpenCL">; def err_opencl_vla : Error< "variable length arrays are not supported in OpenCL">; -def err_event_t_kernel_arg : Error< - "the event_t type cannot be used to declare a kernel function argument">; +def err_bad_kernel_param_type : Error< + "%0 cannot be used as the type of a kernel parameter">; +def err_record_with_pointers_kernel_param : Error< + "%select{struct|union}0 kernel parameters may not contain pointers">; +def note_within_field_of_type : Note< + "within field of type %0 declared here">; +def note_illegal_field_declared_here : Note< + "field of illegal %select{type|pointer type}0 %1 declared here">; def err_event_t_global_var : Error< "the event_t type cannot be used to declare a program scope variable">; def err_event_t_struct_field : Error< @@ -6332,24 +6695,49 @@ def err_wrong_sampler_addressspace: Error< "sampler type cannot be used with the __local and __global address space qualifiers">; def err_opencl_global_invalid_addr_space : Error< "global variables must have a constant address space qualifier">; - +def err_opencl_no_main : Error<"%select{function|kernel}0 cannot be called 'main'">; +} // end of sema category + +let CategoryName = "OpenMP Issue" in { // OpenMP support. +def err_omp_expected_var_arg : Error< + "%0 is not a global variable, static local variable or static data member">; def err_omp_expected_var_arg_suggest : Error< - "%0 is not a global variable, static local variable or static data member%select{|; did you mean %2?}1">; + "%0 is not a global variable, static local variable or static data member; " + "did you mean %1">; def err_omp_global_var_arg : Error< "arguments of '#pragma omp %0' must have %select{global storage|static storage duration}1">; def err_omp_ref_type_arg : Error< "arguments of '#pragma omp %0' cannot be of reference type %1">; def err_omp_var_scope : Error< - "'#pragma omp %0' must appear in the scope of the %1 variable declaration">; + "'#pragma omp %0' must appear in the scope of the %q1 variable declaration">; def err_omp_var_used : Error< - "'#pragma omp %0' must precede all references to variable %1">; + "'#pragma omp %0' must precede all references to variable %q1">; def err_omp_var_thread_local : Error< "variable %0 cannot be threadprivate because it is thread-local">; -def err_omp_incomplete_type : Error< - "a threadprivate variable must not have incomplete type %0">; - -} // end of sema category +def err_omp_private_incomplete_type : Error< + "a private variable with incomplete type %0">; +def err_omp_firstprivate_incomplete_type : Error< + "a firstprivate variable with incomplete type %0">; +def err_omp_unexpected_clause_value : Error < + "expected %0 in OpenMP clause '%1'">; +def err_omp_expected_var_name : Error < + "expected variable name">; +def err_omp_required_method : Error < + "%0 variable must have an accessible, unambiguous %select{default constructor|copy constructor|copy assignment operator|'%2'|destructor}1">; +def err_omp_clause_ref_type_arg : Error< + "arguments of OpenMP clause '%0' cannot be of reference type %1">; +def err_omp_threadprivate_incomplete_type : Error< + "threadprivate variable with incomplete type %0">; +def err_omp_no_dsa_for_variable : Error < + "variable %0 must have explicitly specified data sharing attributes">; +def err_omp_wrong_dsa : Error< + "%0 variable cannot be %1">; +def note_omp_explicit_dsa : Note < + "defined as %0">; +def note_omp_predetermined_dsa : Note < + "predetermined as %0">; +} // end of OpenMP category let CategoryName = "Related Result Type Issue" in { // Objective-C related result type compatibility @@ -6386,6 +6774,8 @@ def err_module_private_local : Error< def err_module_private_local_class : Error< "local %select{struct|interface|union|class|enum}0 cannot be declared " "__module_private__">; +def err_module_private_declaration : Error< + "declaration of %0 must be imported from module '%1' before it is required">; def err_module_private_definition : Error< "definition of %0 must be imported from module '%1' before it is required">; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td index 1b45b10..81509cc 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td @@ -14,7 +14,7 @@ def err_fe_unable_to_read_pch_file : Error< def err_fe_not_a_pch_file : Error< "input is not a PCH file: '%0'">; def err_fe_pch_malformed : Error< - "malformed or corrupted PCH file: '%0'">, DefaultFatal; + "malformed or corrupted AST file: '%0'">, DefaultFatal; def err_fe_pch_malformed_block : Error< "malformed block record in PCH file: '%0'">, DefaultFatal; def err_fe_pch_file_modified : Error< @@ -22,6 +22,8 @@ def err_fe_pch_file_modified : Error< DefaultFatal; def err_fe_pch_file_overridden : Error< "file '%0' from the precompiled header has been overridden">; +def note_module_cache_path : Note< + "after modifying system headers, please delete the module cache at '%0'">; def err_pch_targetopt_mismatch : Error< "PCH file was compiled for the %0 '%1' but the current translation " @@ -65,4 +67,13 @@ def err_pch_pp_detailed_record : Error< def err_not_a_pch_file : Error< "'%0' does not appear to be a precompiled header file">, DefaultFatal; + +def err_module_odr_violation_missing_decl : Error< + "%q0 from module '%1' is not present in definition of %q2" + "%select{ in module '%4'| provided earlier}3">, NoSFINAE; +def note_module_odr_violation_no_possible_decls : Note< + "definition has no member %0">; +def note_module_odr_violation_possible_decl : Note< + "declaration of %0 does not match">; + } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h index 6d9e53b..255eee3 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h @@ -24,6 +24,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/FileSystem.h" // FIXME: Enhance libsystem to support inode and other fields in stat. #include <sys/types.h> @@ -35,7 +36,6 @@ struct stat; namespace llvm { class MemoryBuffer; -namespace sys { class Path; } } namespace clang { @@ -63,9 +63,9 @@ class FileEntry { time_t ModTime; // Modification time of file. const DirectoryEntry *Dir; // Directory file lives in. unsigned UID; // A unique (small) ID for the file. - dev_t Device; // ID for the device containing the file. - ino_t Inode; // Inode number for the file. - mode_t FileMode; // The file mode as returned by 'stat'. + llvm::sys::fs::UniqueID UniqueID; + bool IsNamedPipe; + bool InPCH; /// FD - The file descriptor for the file entry if it is opened and owned /// by the FileEntry. If not, this is set to -1. @@ -73,10 +73,12 @@ class FileEntry { friend class FileManager; public: - FileEntry(dev_t device, ino_t inode, mode_t m) - : Name(0), Device(device), Inode(inode), FileMode(m), FD(-1) {} + FileEntry(llvm::sys::fs::UniqueID UniqueID, bool IsNamedPipe, bool InPCH) + : Name(0), UniqueID(UniqueID), IsNamedPipe(IsNamedPipe), InPCH(InPCH), + FD(-1) {} // Add a default constructor for use with llvm::StringMap - FileEntry() : Name(0), Device(0), Inode(0), FileMode(0), FD(-1) {} + FileEntry() + : Name(0), UniqueID(0, 0), IsNamedPipe(false), InPCH(false), FD(-1) {} FileEntry(const FileEntry &FE) { memcpy(this, &FE, sizeof(FE)); @@ -93,23 +95,22 @@ public: const char *getName() const { return Name; } off_t getSize() const { return Size; } unsigned getUID() const { return UID; } - ino_t getInode() const { return Inode; } - dev_t getDevice() const { return Device; } + const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; } + bool isInPCH() const { return InPCH; } time_t getModificationTime() const { return ModTime; } - mode_t getFileMode() const { return FileMode; } /// \brief Return the directory the file lives in. const DirectoryEntry *getDir() const { return Dir; } - bool operator<(const FileEntry &RHS) const { - return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode); - } + bool operator<(const FileEntry &RHS) const { return UniqueID < RHS.UniqueID; } /// \brief Check whether the file is a named pipe (and thus can't be opened by /// the native FileManager methods). - bool isNamedPipe() const; + bool isNamedPipe() const { return IsNamedPipe; } }; +struct FileData; + /// \brief Implements support for file system lookup, file system caching, /// and directory search management. /// @@ -170,8 +171,8 @@ class FileManager : public RefCountedBase<FileManager> { // Caching. OwningPtr<FileSystemStatCache> StatCache; - bool getStatValue(const char *Path, struct stat &StatBuf, - bool isFile, int *FileDescriptor); + bool getStatValue(const char *Path, FileData &Data, bool isFile, + int *FileDescriptor); /// Add all ancestors of the given path (pointing to either a file /// or a directory) as virtual directories. @@ -244,7 +245,8 @@ public: /// /// If the path is relative, it will be resolved against the WorkingDir of the /// FileManager's FileSystemOptions. - bool getNoncachedStatValue(StringRef Path, struct stat &StatBuf); + bool getNoncachedStatValue(StringRef Path, + llvm::sys::fs::file_status &Result); /// \brief Remove the real file \p Entry from the cache. void invalidateCache(const FileEntry *Entry); diff --git a/contrib/llvm/tools/clang/include/clang/Basic/FileSystemStatCache.h b/contrib/llvm/tools/clang/include/clang/Basic/FileSystemStatCache.h index ff70373..23d8256 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/FileSystemStatCache.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/FileSystemStatCache.h @@ -18,11 +18,21 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Support/FileSystem.h" #include <sys/stat.h> #include <sys/types.h> namespace clang { +struct FileData { + uint64_t Size; + time_t ModTime; + llvm::sys::fs::UniqueID UniqueID; + bool IsDirectory; + bool IsNamedPipe; + bool InPCH; +}; + /// \brief Abstract interface for introducing a FileManager cache for 'stat' /// system calls, which is used by precompiled and pretokenized headers to /// improve performance. @@ -49,10 +59,9 @@ public: /// success for directories (not files). On a successful file lookup, the /// implementation can optionally fill in FileDescriptor with a valid /// descriptor and the client guarantees that it will close it. - static bool get(const char *Path, struct stat &StatBuf, - bool isFile, int *FileDescriptor, FileSystemStatCache *Cache); - - + static bool get(const char *Path, FileData &Data, bool isFile, + int *FileDescriptor, FileSystemStatCache *Cache); + /// \brief Sets the next stat call cache in the chain of stat caches. /// Takes ownership of the given stat cache. void setNextStatCache(FileSystemStatCache *Cache) { @@ -68,18 +77,18 @@ public: FileSystemStatCache *takeNextStatCache() { return NextStatCache.take(); } protected: - virtual LookupResult getStat(const char *Path, struct stat &StatBuf, - bool isFile, int *FileDescriptor) = 0; + virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile, + int *FileDescriptor) = 0; - LookupResult statChained(const char *Path, struct stat &StatBuf, - bool isFile, int *FileDescriptor) { + LookupResult statChained(const char *Path, FileData &Data, bool isFile, + int *FileDescriptor) { if (FileSystemStatCache *Next = getNextStatCache()) - return Next->getStat(Path, StatBuf, isFile, FileDescriptor); - + return Next->getStat(Path, Data, isFile, FileDescriptor); + // If we hit the end of the list of stat caches to try, just compute and // return it without a cache. - return get(Path, StatBuf, - isFile, FileDescriptor, 0) ? CacheMissing : CacheExists; + return get(Path, Data, isFile, FileDescriptor, 0) ? CacheMissing + : CacheExists; } }; @@ -89,16 +98,16 @@ protected: class MemorizeStatCalls : public FileSystemStatCache { public: /// \brief The set of stat() calls that have been seen. - llvm::StringMap<struct stat, llvm::BumpPtrAllocator> StatCalls; - - typedef llvm::StringMap<struct stat, llvm::BumpPtrAllocator>::const_iterator + llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls; + + typedef llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator iterator; - + iterator begin() const { return StatCalls.begin(); } iterator end() const { return StatCalls.end(); } - - virtual LookupResult getStat(const char *Path, struct stat &StatBuf, - bool isFile, int *FileDescriptor); + + virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile, + int *FileDescriptor); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h index d4d5339..304ff36 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h @@ -19,6 +19,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/TokenKinds.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/PointerLikeTypeTraits.h" @@ -147,7 +148,7 @@ public: return HadMacro; } - /// getTokenID - If this is a source-language token (e.g. 'for'), this API + /// If this is a source-language token (e.g. 'for'), this API /// can be used to cause the lexer to map identifiers to source-language /// tokens. tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; } @@ -183,8 +184,9 @@ public: } void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; } - /// getBuiltinID - Return a value indicating whether this is a builtin - /// function. 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. + /// \brief Return a value indicating whether this is a builtin function. + /// + /// 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. /// 2+ are specific builtin functions. unsigned getBuiltinID() const { if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS) @@ -236,7 +238,7 @@ public: RecomputeNeedsHandleIdentifier(); } - /// isPoisoned - Return true if this token has been poisoned. + /// \brief Return true if this token has been poisoned. bool isPoisoned() const { return IsPoisoned; } /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether @@ -256,12 +258,14 @@ public: T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); } void setFETokenInfo(void *T) { FETokenInfo = T; } - /// isHandleIdentifierCase - Return true if the Preprocessor::HandleIdentifier - /// must be called on a token of this identifier. If this returns false, we - /// know that HandleIdentifier will not affect the token. + /// \brief Return true if the Preprocessor::HandleIdentifier must be called + /// on a token of this identifier. + /// + /// If this returns false, we know that HandleIdentifier will not affect + /// the token. bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; } - /// isFromAST - Return true if the identifier in its current state was loaded + /// \brief Return true if the identifier in its current state was loaded /// from an AST file. bool isFromAST() const { return IsFromAST; } @@ -293,12 +297,10 @@ public: RecomputeNeedsHandleIdentifier(); } - /// \brief Determine whether this is the contextual keyword - /// 'import'. + /// \brief Determine whether this is the contextual keyword \c import. bool isModulesImport() const { return IsModulesImport; } - /// \brief Set whether this identifier is the contextual keyword - /// 'import'. + /// \brief Set whether this identifier is the contextual keyword \c import. void setModulesImport(bool I) { IsModulesImport = I; if (I) @@ -308,10 +310,9 @@ public: } private: - /// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does - /// several special (but rare) things to identifiers of various sorts. For - /// example, it changes the "for" keyword token from tok::identifier to - /// tok::for. + /// The Preprocessor::HandleIdentifier does several special (but rare) + /// things to identifiers of various sorts. For example, it changes the + /// \c for keyword token from tok::identifier to tok::for. /// /// This method is very tied to the definition of HandleIdentifier. Any /// change to it should be reflected here. @@ -323,9 +324,10 @@ private: } }; -/// \brief an RAII object for [un]poisoning an identifier -/// within a certain scope. II is allowed to be null, in -/// which case, objects of this type have no effect. +/// \brief An RAII object for [un]poisoning an identifier within a scope. +/// +/// \p II is allowed to be null, in which case objects of this type have +/// no effect. class PoisonIdentifierRAIIObject { IdentifierInfo *const II; const bool OldValue; @@ -371,17 +373,16 @@ public: virtual StringRef Next() = 0; }; -/// IdentifierInfoLookup - An abstract class used by IdentifierTable that -/// provides an interface for performing lookups from strings -/// (const char *) to IdentiferInfo objects. +/// \brief Provides lookups to, and iteration over, IdentiferInfo objects. class IdentifierInfoLookup { public: virtual ~IdentifierInfoLookup(); - /// get - Return the identifier token info for the specified named identifier. - /// Unlike the version in IdentifierTable, this returns a pointer instead - /// of a reference. If the pointer is NULL then the IdentifierInfo cannot - /// be found. + /// \brief Return the IdentifierInfo for the specified named identifier. + /// + /// Unlike the version in IdentifierTable, this returns a pointer instead + /// of a reference. If the pointer is null then the IdentifierInfo cannot + /// be found. virtual IdentifierInfo* get(StringRef Name) = 0; /// \brief Retrieve an iterator into the set of all identifiers @@ -577,6 +578,19 @@ enum { ObjCMethodFamilyBitWidth = 4 }; /// \brief An invalid value of ObjCMethodFamily. enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 }; +/// \brief A family of Objective-C methods. +/// +/// These are family of methods whose result type is initially 'id', but +/// but are candidate for the result type to be changed to 'instancetype'. +enum ObjCInstanceTypeFamily { + OIT_None, + OIT_Array, + OIT_Dictionary, + OIT_Singleton, + OIT_Init, + OIT_ReturnsSelf +}; + /// \brief Smart pointer class that efficiently represents Objective-C method /// names. /// @@ -697,6 +711,8 @@ public: static Selector getTombstoneMarker() { return Selector(uintptr_t(-2)); } + + static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel); }; /// \brief This table allows us to fully hide how we implement @@ -725,13 +741,19 @@ public: /// \brief Return the total amount of memory allocated for managing selectors. size_t getTotalMemory() const; - /// \brief Return the setter name for the given identifier. + /// \brief Return the default setter name for the given identifier. + /// + /// This is "set" + \p Name where the initial character of \p Name + /// has been capitalized. + static SmallString<64> constructSetterName(StringRef Name); + + /// \brief Return the default setter selector for the given identifier. /// /// This is "set" + \p Name where the initial character of \p Name /// has been capitalized. - static Selector constructSetterName(IdentifierTable &Idents, - SelectorTable &SelTable, - const IdentifierInfo *Name); + static Selector constructSetterSelector(IdentifierTable &Idents, + SelectorTable &SelTable, + const IdentifierInfo *Name); }; /// DeclarationNameExtra - Common base of the MultiKeywordSelector, diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Lambda.h b/contrib/llvm/tools/clang/include/clang/Basic/Lambda.h index b1ad6ac..280ae94 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Lambda.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Lambda.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief Defines several types used to describe C++ lambda expressions +/// \brief Defines several types used to describe C++ lambda expressions /// that are shared between the parser and AST. /// //===----------------------------------------------------------------------===// @@ -26,12 +26,15 @@ enum LambdaCaptureDefault { LCD_ByRef }; -/// \brief The different capture forms in a lambda introducer: 'this' or a -/// copied or referenced variable. +/// \brief The different capture forms in a lambda introducer +/// +/// C++11 allows capture of \c this, or of local variables by copy or +/// by reference. C++1y also allows "init-capture", where the initializer +/// is an expression. enum LambdaCaptureKind { - LCK_This, - LCK_ByCopy, - LCK_ByRef + LCK_This, ///< Capturing the \c this pointer + LCK_ByCopy, ///< Capturing by copy (a.k.a., by value) + LCK_ByRef ///< Capturing by reference }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def index 2a3a26a..2729f79 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def @@ -1,4 +1,4 @@ -//===--- LangOptions.def - Language option database --------------- C++ -*-===// +//===--- LangOptions.def - Language option database -------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file defines the language options. Users of this file must -// define the LANGOPT macro to make use of this information. +// define the LANGOPT macro to make use of this information. // Optionally, the user may also define BENIGN_LANGOPT // (for options that don't affect the construction of the AST in an // incompatible way), ENUM_LANGOPT (for options that have enumeration, @@ -52,11 +52,11 @@ LANGOPT(CPlusPlus11 , 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, +BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, "Objective-C auto-synthesized properties") -BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0, +BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0, "Encoding extended block type signature") -BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1, +BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1, "Objective-C related result type inference") LANGOPT(Trigraphs , 1, 0,"trigraphs") LANGOPT(LineComment , 1, 0, "'//' comments") @@ -86,6 +86,7 @@ LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout") LANGOPT(Freestanding, 1, 0, "freestanding implementation") LANGOPT(FormatExtensions , 1, 0, "FreeBSD format extensions") LANGOPT(NoBuiltin , 1, 0, "disable builtin functions") +LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions") BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers") LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") @@ -94,10 +95,11 @@ BENIGN_LANGOPT(EmitAllDecls , 1, 0, "support for emitting all declarations" LANGOPT(MathErrno , 1, 1, "errno support for math functions") BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time") LANGOPT(Modules , 1, 0, "modules extension to C") +LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses") LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro") LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro") LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") -VALUE_LANGOPT(PackStruct , 32, 0, +VALUE_LANGOPT(PackStruct , 32, 0, "default struct packing maximum alignment") VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level") VALUE_LANGOPT(PIELevel , 2, 0, "__PIE__ level") @@ -122,6 +124,7 @@ LANGOPT(CUDA , 1, 0, "CUDA") LANGOPT(OpenMP , 1, 0, "OpenMP support") LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators") +LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions") BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision") 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") @@ -141,31 +144,37 @@ 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(ObjCARCWeak , 1, 0, "__weak support in the ARC runtime") +LANGOPT(ObjCSubscriptingLegacyRuntime , 1, 0, "Subscripting support in legacy ObjectiveC runtime") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") +ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode") LANGOPT(MRTD , 1, 0, "-mrtd calling convention") BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing") LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime") ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode") -ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility, +ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility, "value symbol visibility") -ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility, +ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility, "type symbol visibility") -ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, +ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, "stack protector mode") ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, "signed integer overflow handling") -BENIGN_LANGOPT(InstantiationDepth, 32, 256, +BENIGN_LANGOPT(ArrowDepth, 32, 256, + "maximum number of operator->s to follow") +BENIGN_LANGOPT(InstantiationDepth, 32, 256, "maximum template instantiation depth") BENIGN_LANGOPT(ConstexprCallDepth, 32, 512, "maximum constexpr call depth") +BENIGN_LANGOPT(ConstexprStepLimit, 32, 1048576, + "maximum constexpr evaluation steps") BENIGN_LANGOPT(BracketDepth, 32, 256, "maximum bracket nesting depth") -BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0, +BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0, "if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.") -VALUE_LANGOPT(MSCVersion, 32, 0, +VALUE_LANGOPT(MSCVersion, 32, 0, "version of Microsoft Visual C/C++") LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling") diff --git a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h index 21ca7eb..d4e8b4e 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h @@ -66,6 +66,8 @@ public: SOB_Trapping // -ftrapv }; + enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; + public: clang::ObjCRuntime ObjCRuntime; @@ -95,6 +97,11 @@ public: bool isSignedOverflowDefined() const { return getSignedOverflowBehavior() == SOB_Defined; } + + bool isSubscriptPointerArithmetic() const { + return ObjCRuntime.isSubscriptPointerArithmetic() && + !ObjCSubscriptingLegacyRuntime; + } /// \brief Reset all of the options that are not considered when building a /// module. diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Linkage.h b/contrib/llvm/tools/clang/include/clang/Basic/Linkage.h index 01b8db1..6996207 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Linkage.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Linkage.h @@ -37,6 +37,10 @@ enum Linkage { /// point of view. UniqueExternalLinkage, + /// \brief No linkage according to the standard, but is visible from other + /// translation units because of types defined in a inline function. + VisibleNoLinkage, + /// \brief External linkage, which indicates that the entity can /// be referred to from other translation units. ExternalLinkage @@ -62,14 +66,40 @@ enum GVALinkage { GVA_ExplicitTemplateInstantiation }; -/// \brief Determine whether the given linkage is semantically external. -inline bool isExternalLinkage(Linkage L) { - return L == UniqueExternalLinkage || L == ExternalLinkage; +inline bool isExternallyVisible(Linkage L) { + return L == ExternalLinkage || L == VisibleNoLinkage; +} + +inline Linkage getFormalLinkage(Linkage L) { + if (L == UniqueExternalLinkage) + return ExternalLinkage; + if (L == VisibleNoLinkage) + return NoLinkage; + return L; } -/// \brief Compute the minimum linkage given two linages. +inline bool isExternalFormalLinkage(Linkage L) { + return getFormalLinkage(L) == ExternalLinkage; +} + +/// \brief Compute the minimum linkage given two linkages. +/// +/// The linkage can be interpreted as a pair formed by the formal linkage and +/// a boolean for external visibility. This is just what getFormalLinkage and +/// isExternallyVisible return. We want the minimum of both components. The +/// Linkage enum is defined in an order that makes this simple, we just need +/// special cases for when VisibleNoLinkage would lose the visible bit and +/// become NoLinkage. inline Linkage minLinkage(Linkage L1, Linkage L2) { - return L1 < L2? L1 : L2; + if (L2 == VisibleNoLinkage) + std::swap(L1, L2); + if (L1 == VisibleNoLinkage) { + if (L2 == InternalLinkage) + return NoLinkage; + if (L2 == UniqueExternalLinkage) + return NoLinkage; + } + return L1 < L2 ? L1 : L2; } } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Module.h b/contrib/llvm/tools/clang/include/clang/Basic/Module.h index d2a43f0..e8d774e 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Module.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Module.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_BASIC_MODULE_H #include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SetVector.h" @@ -37,6 +38,7 @@ class FileEntry; class FileManager; class LangOptions; class TargetInfo; +class IdentifierInfo; /// \brief Describes the name of a module. typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; @@ -75,19 +77,28 @@ private: /// \brief top-level header filenames that aren't resolved to FileEntries yet. std::vector<std::string> TopHeaderNames; + /// \brief Cache of modules visible to lookup in this module. + mutable llvm::DenseSet<const Module*> VisibleModulesCache; + public: /// \brief The headers that are part of this module. - SmallVector<const FileEntry *, 2> Headers; + SmallVector<const FileEntry *, 2> NormalHeaders; /// \brief The headers that are explicitly excluded from this module. SmallVector<const FileEntry *, 2> ExcludedHeaders; + /// \brief The headers that are private to this module. + llvm::SmallVector<const FileEntry *, 2> PrivateHeaders; + + /// \brief An individual requirement: a feature name and a flag indicating + /// the required state of that feature. + typedef std::pair<std::string, bool> Requirement; + /// \brief The set of language features required to use this module. /// - /// If any of these features is not present, the \c IsAvailable bit - /// will be false to indicate that this (sub)module is not - /// available. - SmallVector<std::string, 2> Requires; + /// If any of these requirements are not available, the \c IsAvailable bit + /// will be false to indicate that this (sub)module is not available. + SmallVector<Requirement, 2> Requirements; /// \brief Whether this module is available in the current /// translation unit. @@ -176,6 +187,12 @@ public: /// \brief The set of export declarations that have yet to be resolved. SmallVector<UnresolvedExportDecl, 2> UnresolvedExports; + /// \brief The directly used modules. + SmallVector<Module *, 2> DirectUses; + + /// \brief The set of use declarations that have yet to be resolved. + SmallVector<ModuleId, 2> UnresolvedDirectUses; + /// \brief A library or framework to link against when an entity from this /// module is used. struct LinkLibrary { @@ -254,12 +271,12 @@ public: /// /// \param Target The target options used for the current translation unit. /// - /// \param Feature If this module is unavailable, this parameter - /// will be set to one of the features that is required for use of - /// this module (but is not available). + /// \param Req If this module is unavailable, this parameter + /// will be set to one of the requirements that is not met for use of + /// this module. bool isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, - StringRef &Feature) const; + Requirement &Req) const; /// \brief Determine whether this module is a submodule. bool isSubModule() const { return Parent != 0; } @@ -353,12 +370,16 @@ public: /// \param Feature The feature that is required by this module (and /// its submodules). /// + /// \param RequiredState The required state of this feature: \c true + /// if it must be present, \c false if it must be absent. + /// /// \param LangOpts The set of language options that will be used to /// evaluate the availability of this feature. /// /// \param Target The target options that will be used to evaluate the /// availability of this feature. - void addRequirement(StringRef Feature, const LangOptions &LangOpts, + void addRequirement(StringRef Feature, bool RequiredState, + const LangOptions &LangOpts, const TargetInfo &Target); /// \brief Find the submodule with the given name. @@ -366,6 +387,14 @@ public: /// \returns The submodule if found, or NULL otherwise. Module *findSubmodule(StringRef Name) const; + /// \brief Determine whether the specified module would be visible to + /// a lookup at the end of this module. + bool isModuleVisible(const Module *M) const { + if (VisibleModulesCache.empty()) + buildVisibleModulesCache(); + return VisibleModulesCache.count(M); + } + typedef std::vector<Module *>::iterator submodule_iterator; typedef std::vector<Module *>::const_iterator submodule_const_iterator; @@ -374,7 +403,10 @@ public: submodule_iterator submodule_end() { return SubModules.end(); } submodule_const_iterator submodule_end() const { return SubModules.end(); } - /// \brief Returns the exported modules based on the wildcard restrictions. + /// \brief Appends this module's list of exported modules to \p Exported. + /// + /// This provides a subset of immediately imported modules (the ones that are + /// directly exported), not the complete set of exported modules. void getExportedModules(SmallVectorImpl<Module *> &Exported) const; static StringRef getModuleInputBufferName() { @@ -387,6 +419,9 @@ public: /// \brief Dump the contents of this module to the given output stream. void dump() const; + +private: + void buildVisibleModulesCache() const; }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h b/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h index 18ef64a..4c64497 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h @@ -79,7 +79,7 @@ public: case GCC: return false; case MacOSX: return true; case GNUstep: return true; - case ObjFW: return false; + case ObjFW: return true; case iOS: return true; } llvm_unreachable("bad kind"); @@ -98,9 +98,8 @@ public: Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) return false; - // Mac runtimes use legacy dispatch everywhere except x86-64 - } else if (isNeXTFamily() && isNonFragile()) - return Arch != llvm::Triple::x86_64; + } + // Mac runtimes use legacy dispatch everywhere now. return true; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.def index f968977..6d1a7b2 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.def @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// /// \file -/// \brief This file defines the list of supported OpenMP directives and +/// \brief This file defines the list of supported OpenMP directives and /// clauses. /// //===----------------------------------------------------------------------===// @@ -15,9 +15,38 @@ #ifndef OPENMP_DIRECTIVE # define OPENMP_DIRECTIVE(Name) #endif +#ifndef OPENMP_CLAUSE +# define OPENMP_CLAUSE(Name, Class) +#endif +#ifndef OPENMP_PARALLEL_CLAUSE +# define OPENMP_PARALLEL_CLAUSE(Name) +#endif +#ifndef OPENMP_DEFAULT_KIND +# define OPENMP_DEFAULT_KIND(Name) +#endif // OpenMP directives. OPENMP_DIRECTIVE(threadprivate) OPENMP_DIRECTIVE(parallel) +OPENMP_DIRECTIVE(task) + +// OpenMP clauses. +OPENMP_CLAUSE(default, OMPDefaultClause) +OPENMP_CLAUSE(private, OMPPrivateClause) +OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause) +OPENMP_CLAUSE(shared, OMPSharedClause) + +// Clauses allowed for OpenMP directives. +OPENMP_PARALLEL_CLAUSE(default) +OPENMP_PARALLEL_CLAUSE(private) +OPENMP_PARALLEL_CLAUSE(firstprivate) +OPENMP_PARALLEL_CLAUSE(shared) + +// Static attributes for 'default' clause. +OPENMP_DEFAULT_KIND(none) +OPENMP_DEFAULT_KIND(shared) +#undef OPENMP_DEFAULT_KIND #undef OPENMP_DIRECTIVE +#undef OPENMP_CLAUSE +#undef OPENMP_PARALLEL_CLAUSE diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.h b/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.h index c90e9a0..5b45731 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.h @@ -28,9 +28,37 @@ enum OpenMPDirectiveKind { NUM_OPENMP_DIRECTIVES }; +/// \brief OpenMP clauses. +enum OpenMPClauseKind { + OMPC_unknown = 0, +#define OPENMP_CLAUSE(Name, Class) \ + OMPC_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_threadprivate, + NUM_OPENMP_CLAUSES +}; + +/// \brief OpenMP attributes for 'default' clause. +enum OpenMPDefaultClauseKind { + OMPC_DEFAULT_unknown = 0, +#define OPENMP_DEFAULT_KIND(Name) \ + OMPC_DEFAULT_##Name, +#include "clang/Basic/OpenMPKinds.def" + NUM_OPENMP_DEFAULT_KINDS +}; + OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str); const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind); +OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str); +const char *getOpenMPClauseName(OpenMPClauseKind Kind); + +unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str); +const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type); + +bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind, + OpenMPClauseKind CKind); + } #endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.h b/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.h index 108014f..2ceab9c 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.h @@ -30,7 +30,7 @@ enum OverloadedOperatorKind { /// \brief Retrieve the spelling of the given overloaded operator, without /// the preceding "operator" keyword. const char *getOperatorSpelling(OverloadedOperatorKind Operator); - + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h index 3f68160..dd29926 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h @@ -368,6 +368,27 @@ public: } friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + const IdentifierInfo *II) { + PD.AddTaggedVal(reinterpret_cast<intptr_t>(II), + DiagnosticsEngine::ak_identifierinfo); + return PD; + } + + // Adds a DeclContext to the diagnostic. The enable_if template magic is here + // so that we only match those arguments that are (statically) DeclContexts; + // other arguments that derive from DeclContext (e.g., RecordDecls) will not + // match. + template<typename T> + friend inline + typename llvm::enable_if<llvm::is_same<T, DeclContext>, + const PartialDiagnostic &>::type + operator<<(const PartialDiagnostic &PD, T *DC) { + PD.AddTaggedVal(reinterpret_cast<intptr_t>(DC), + DiagnosticsEngine::ak_declcontext); + return PD; + } + + friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, const SourceRange &R) { PD.AddSourceRange(CharSourceRange::getTokenRange(R)); return PD; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def b/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def index 709ec8d..c9b31a3 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def @@ -54,13 +54,17 @@ SANITIZER("memory", Memory) // ThreadSanitizer SANITIZER("thread", Thread) +// LeakSanitizer +SANITIZER("leak", Leak) + // UndefinedBehaviorSanitizer SANITIZER("alignment", Alignment) +SANITIZER("array-bounds", ArrayBounds) SANITIZER("bool", Bool) -SANITIZER("bounds", Bounds) SANITIZER("enum", Enum) SANITIZER("float-cast-overflow", FloatCastOverflow) SANITIZER("float-divide-by-zero", FloatDivideByZero) +SANITIZER("function", Function) SANITIZER("integer-divide-by-zero", IntegerDivideByZero) SANITIZER("null", Null) SANITIZER("object-size", ObjectSize) @@ -74,20 +78,23 @@ SANITIZER("vptr", Vptr) // IntegerSanitizer SANITIZER("unsigned-integer-overflow", UnsignedIntegerOverflow) +// DataFlowSanitizer +SANITIZER("dataflow", DataFlow) + // -fsanitize=undefined includes all the sanitizers which have low overhead, no // ABI or address space layout implications, and only catch undefined behavior. SANITIZER_GROUP("undefined", Undefined, - Alignment | Bool | Bounds | Enum | FloatCastOverflow | - FloatDivideByZero | IntegerDivideByZero | Null | ObjectSize | - Return | Shift | SignedIntegerOverflow | Unreachable | - VLABound | Vptr) + Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow | + FloatDivideByZero | Function | IntegerDivideByZero | Null | + ObjectSize | Return | Shift | SignedIntegerOverflow | + Unreachable | VLABound | Vptr) // -fsanitize=undefined-trap (and its alias -fcatch-undefined-behavior) includes // all sanitizers included by -fsanitize=undefined, except those that require // runtime support. This group is generally used in conjunction with the // -fsanitize-undefined-trap-on-error flag. SANITIZER_GROUP("undefined-trap", UndefinedTrap, - Alignment | Bool | Bounds | Enum | FloatCastOverflow | + Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow | FloatDivideByZero | IntegerDivideByZero | Null | ObjectSize | Return | Shift | SignedIntegerOverflow | Unreachable | VLABound) @@ -96,5 +103,9 @@ SANITIZER_GROUP("integer", Integer, SignedIntegerOverflow | UnsignedIntegerOverflow | Shift | IntegerDivideByZero) +// -fbounds-checking +SANITIZER("local-bounds", LocalBounds) +SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds) + #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 143beb6..10ae07b 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h @@ -89,7 +89,7 @@ class SourceLocation { friend class SourceManager; friend class ASTReader; friend class ASTWriter; - enum { + enum LLVM_ENUM_INT_TYPE(unsigned) { MacroIDBit = 1U << 31 }; public: diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h index f82b196..6aab998 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h @@ -1005,7 +1005,7 @@ public: return SourceLocation(); unsigned FileOffset = Entry.getOffset(); - return SourceLocation::getFileLoc(FileOffset + getFileIDSize(FID) - 1); + return SourceLocation::getFileLoc(FileOffset + getFileIDSize(FID)); } /// \brief Returns the include location if \p FID is a \#include'd file @@ -1161,6 +1161,22 @@ public: /// expansion but not the expansion of an argument to a function-like macro. bool isMacroBodyExpansion(SourceLocation Loc) const; + /// \brief Returns true if the given MacroID location points at the beginning + /// of the immediate macro expansion. + /// + /// \param MacroBegin If non-null and function returns true, it is set to the + /// begin location of the immediate macro expansion. + bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc, + SourceLocation *MacroBegin = 0) const; + + /// \brief Returns true if the given MacroID location points at the character + /// end of the immediate macro expansion. + /// + /// \param MacroEnd If non-null and function returns true, it is set to the + /// character end location of the immediate macro expansion. + bool isAtEndOfImmediateMacroExpansion(SourceLocation Loc, + SourceLocation *MacroEnd = 0) const; + /// \brief Returns true if \p Loc is inside the [\p Start, +\p Length) /// chunk of the source location address space. /// @@ -1276,14 +1292,28 @@ public: PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives = true) const; - /// \brief Returns true if both SourceLocations correspond to the same file. - bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const { + /// \brief Returns whether the PresumedLoc for a given SourceLocation is + /// in the main file. + /// + /// This computes the "presumed" location for a SourceLocation, then checks + /// whether it came from a file other than the main file. This is different + /// from isWrittenInMainFile() because it takes line marker directives into + /// account. + bool isInMainFile(SourceLocation Loc) const; + + /// \brief Returns true if the spelling locations for both SourceLocations + /// are part of the same file buffer. + /// + /// This check ignores line marker directives. + bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const { return getFileID(Loc1) == getFileID(Loc2); } - /// \brief Returns true if the file of provided SourceLocation is the main - /// file. - bool isFromMainFile(SourceLocation Loc) const { + /// \brief Returns true if the spelling location for the given location + /// is in the main file buffer. + /// + /// This check ignores line marker directives. + bool isWrittenInMainFile(SourceLocation Loc) const { return getFileID(Loc) == getMainFileID(); } @@ -1467,7 +1497,7 @@ public: if (Invalid) *Invalid = true; return LocalSLocEntryTable[0]; } - return getSLocEntryByID(FID.ID); + return getSLocEntryByID(FID.ID, Invalid); } unsigned getNextLocalOffset() const { return NextLocalOffset; } @@ -1531,11 +1561,11 @@ private: const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const; /// \brief Get the entry with the given unwrapped FileID. - const SrcMgr::SLocEntry &getSLocEntryByID(int ID) const { + const SrcMgr::SLocEntry &getSLocEntryByID(int ID, bool *Invalid = 0) const { assert(ID != -1 && "Using FileID sentinel value"); if (ID < 0) - return getLoadedSLocEntryByID(ID); - return getLocalSLocEntry(static_cast<unsigned>(ID)); + return getLoadedSLocEntryByID(ID, Invalid); + return getLocalSLocEntry(static_cast<unsigned>(ID), Invalid); } const SrcMgr::SLocEntry &getLoadedSLocEntryByID(int ID, @@ -1570,6 +1600,14 @@ private: return SLocOffset < getSLocEntryByID(FID.ID+1).getOffset(); } + /// \brief Returns the previous in-order FileID or an invalid FileID if there + /// is no previous one. + FileID getPreviousFileID(FileID FID) const; + + /// \brief Returns the next in-order FileID or an invalid FileID if there is + /// no next one. + FileID getNextFileID(FileID FID) const; + /// \brief Create a new fileID for the specified ContentCache and /// include position. /// diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h index 6c7d39e..0b80939 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h @@ -131,8 +131,8 @@ namespace clang { OK_ObjCSubscript }; - // \brief Describes the kind of template specialization that a - // particular template specialization declaration represents. + /// \brief Describes the kind of template specialization that a + /// particular template specialization declaration represents. enum TemplateSpecializationKind { /// This template specialization was formed from a template-id but /// has not yet been declared, defined, or instantiated. @@ -154,6 +154,13 @@ namespace clang { TSK_ExplicitInstantiationDefinition }; + /// \brief Determine whether this template specialization kind refers + /// to an instantiation of an entity (as opposed to a non-template or + /// an explicit specialization). + inline bool isTemplateInstantiation(TemplateSpecializationKind Kind) { + return Kind != TSK_Undeclared && Kind != TSK_ExplicitSpecialization; + } + /// \brief Thread storage-class-specifier. enum ThreadStorageClassSpecifier { TSCS_unspecified, @@ -200,7 +207,6 @@ namespace clang { /// \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)) @@ -214,6 +220,27 @@ namespace clang { CC_IntelOclBicc // __attribute__((intel_ocl_bicc)) }; + /// \brief Checks whether the given calling convention is callee-cleanup. + inline bool isCalleeCleanup(CallingConv CC) { + switch (CC) { + case CC_X86StdCall: + case CC_X86FastCall: + case CC_X86ThisCall: + case CC_X86Pascal: + return true; + default: + return false; + } + } + + /// \brief The storage duration for an object (per C++ [basic.stc]). + enum StorageDuration { + SD_FullExpression, ///< Full-expression storage duration (for temporaries). + SD_Automatic, ///< Automatic storage duration (most local variables). + SD_Thread, ///< Thread storage duration. + SD_Static, ///< Static storage duration. + SD_Dynamic ///< Dynamic storage duration. + }; } // 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 cbfce83..69851a9 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td @@ -110,6 +110,7 @@ def CXXThrowExpr : DStmt<Expr>; def CXXDefaultArgExpr : DStmt<Expr>; def CXXDefaultInitExpr : DStmt<Expr>; def CXXScalarValueInitExpr : DStmt<Expr>; +def CXXStdInitializerListExpr : DStmt<Expr>; def CXXNewExpr : DStmt<Expr>; def CXXDeleteExpr : DStmt<Expr>; def CXXPseudoDestructorExpr : DStmt<Expr>; @@ -161,6 +162,7 @@ def CUDAKernelCallExpr : DStmt<CallExpr>; // Clang Extensions. def ShuffleVectorExpr : DStmt<Expr>; +def ConvertVectorExpr : DStmt<Expr>; def BlockExpr : DStmt<Expr>; def OpaqueValueExpr : DStmt<Expr>; @@ -174,3 +176,7 @@ def MSDependentExistsStmt : Stmt; // OpenCL Extensions. def AsTypeExpr : DStmt<Expr>; + +// OpenMP Directives. +def OMPExecutableDirective : Stmt<1>; +def OMPParallelDirective : DStmt<OMPExecutableDirective>; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h index 66e378f..ed3cc49 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h @@ -90,8 +90,10 @@ namespace clang { Int64, Poly8, Poly16, + Poly64, Float16, - Float32 + Float32, + Float64 }; NeonTypeFlags(unsigned F) : Flags(F) {} @@ -130,6 +132,16 @@ namespace clang { LastTSBuiltin }; } + + /// \brief XCore builtins + namespace XCore { + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsXCore.def" + LastTSBuiltin + }; + } } // end namespace clang. #endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetCXXABI.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetCXXABI.h index c9d28f8..1590cca 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetCXXABI.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetCXXABI.h @@ -131,24 +131,36 @@ public: /// \brief Is the default C++ member function calling convention /// the same as the default calling convention? bool isMemberFunctionCCDefault() const { - // Right now, this is always true for Microsoft. + // Right now, this is always false for Microsoft. return !isMicrosoft(); } + /// Are temporary objects passed by value to a call destroyed by the callee? + /// This is a fundamental language change, since it implies that objects + /// passed by value do *not* live to the end of the full expression. + /// Temporaries passed to a function taking a const reference live to the end + /// of the full expression as usual. Both the caller and the callee must + /// have access to the destructor, while only the caller needs the + /// destructor if this is false. + bool isArgumentDestroyedByCallee() const { + return isMicrosoft(); + } + /// \brief Does this ABI have different entrypoints for complete-object /// and base-subobject constructors? bool hasConstructorVariants() const { return isItaniumFamily(); } - /// \brief Does this ABI have different entrypoints for complete-object - /// and base-subobject destructors? - bool hasDestructorVariants() const { + /// \brief Does this ABI allow virtual bases to be primary base classes? + bool hasPrimaryVBases() const { return isItaniumFamily(); } - /// \brief Does this ABI allow virtual bases to be primary base classes? - bool hasPrimaryVBases() const { + /// \brief Does this ABI use key functions? If so, class data such as the + /// vtable is emitted with strong linkage by the TU containing the key + /// function. + bool hasKeyFunctions() const { return isItaniumFamily(); } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h index 49b26ac..047872d 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h @@ -86,7 +86,7 @@ protected: unsigned ComplexLongDoubleUsesFP2Ret : 1; // TargetInfo Constructor. Default initializes all fields. - TargetInfo(const std::string &T); + TargetInfo(const llvm::Triple &T); public: /// \brief Construct a target for the given options. @@ -112,6 +112,8 @@ public: ///===---- Target Data Type Query Methods -------------------------------===// enum IntType { NoInt = 0, + SignedChar, + UnsignedChar, SignedShort, UnsignedShort, SignedInt, @@ -123,6 +125,7 @@ public: }; enum RealType { + NoFloat = 255, Float = 0, Double, LongDouble @@ -199,6 +202,10 @@ protected: /// zero length bitfield, regardless of the zero length bitfield type. unsigned ZeroLengthBitfieldBoundary; + /// \brief Specify if mangling based on address space map should be used or + /// not for language specific address spaces + bool UseAddrSpaceMapMangling; + public: IntType getSizeType() const { return SizeType; } IntType getIntMaxType() const { return IntMaxType; } @@ -220,6 +227,12 @@ public: /// For example, SignedInt -> getIntWidth(). unsigned getTypeWidth(IntType T) const; + /// \brief Return integer type with specified width. + IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const; + + /// \brief Return floating point type with specified width. + RealType getRealTypeByWidth(unsigned BitWidth) const; + /// \brief Return the alignment (in bits) of the specified integer type enum. /// /// For example, SignedInt -> getIntAlign(). @@ -345,11 +358,11 @@ public: unsigned getUnwindWordWidth() const { return getPointerWidth(0); } /// \brief Return the "preferred" register width on this target. - uint64_t getRegisterWidth() const { + unsigned getRegisterWidth() const { // Currently we assume the register width on the target matches the pointer // width, we can introduce a new variable for this if/when some target wants // it. - return LongWidth; + return PointerWidth; } /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro, @@ -422,6 +435,12 @@ public: return ComplexLongDoubleUsesFP2Ret; } + /// \brief Specify if mangling based on address space map should be used or + /// not for language specific address spaces + bool useAddressSpaceMapMangling() const { + return UseAddrSpaceMapMangling; + } + ///===---- Other target property query methods --------------------------===// /// \brief Appends the target-specific \#define values for this @@ -653,6 +672,13 @@ public: return false; } + /// \brief Use the specified unit for FP math. + /// + /// \return False on error (invalid unit name). + virtual bool setFPMath(StringRef Name) { + return false; + } + /// \brief Use this specified C++ ABI. /// /// \return False on error (invalid C++ ABI name). @@ -672,12 +698,10 @@ public: /// \brief Enable or disable a specific target feature; /// the feature name must be valid. - /// - /// \return False on error (invalid feature name). - virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, + virtual void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, bool Enabled) const { - return false; + Features[Name] = Enabled; } /// \brief Perform initialization based on the user configured @@ -687,7 +711,11 @@ public: /// /// The target may modify the features list, to change which options are /// passed onwards to the backend. - virtual void HandleTargetFeatures(std::vector<std::string> &Features) { + /// + /// \return False on error. + virtual bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { + return true; } /// \brief Determine whether the given target has the given feature. @@ -770,7 +798,6 @@ public: default: return CCCR_Warning; case CC_C: - case CC_Default: return CCCR_OK; } } @@ -790,7 +817,7 @@ protected: virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, unsigned &NumAliases) const = 0; virtual void getGCCAddlRegNames(const AddlRegName *&Addl, - unsigned &NumAddl) const { + unsigned &NumAddl) const { Addl = 0; NumAddl = 0; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h index c2183fd..9909182 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetOptions.h @@ -32,6 +32,9 @@ public: /// If given, the name of the target CPU to generate code for. std::string CPU; + /// If given, the unit to use for floating point math. + std::string FPMath; + /// If given, the name of the target ABI to use. std::string ABI; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TemplateKinds.h b/contrib/llvm/tools/clang/include/clang/Basic/TemplateKinds.h index dda011a..c521893 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TemplateKinds.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TemplateKinds.h @@ -27,6 +27,9 @@ enum TemplateNameKind { /// type. The template itself could be a class template, template /// template parameter, or C++0x template alias. TNK_Type_template, + /// The name refers to a variable template whose specialization produces a + /// variable. + TNK_Var_template, /// The name refers to a dependent template name. Whether the /// template name is assumed to refer to a type template or a /// function template depends on the context in which the template diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def index bcf0f31..6812cce 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def @@ -270,7 +270,7 @@ KEYWORD(__objc_no , KEYALL) // C++ 2.11p1: Keywords. KEYWORD(asm , KEYCXX|KEYGNU) -KEYWORD(bool , BOOLSUPPORT|KEYALTIVEC) +KEYWORD(bool , BOOLSUPPORT) KEYWORD(catch , KEYCXX) KEYWORD(class , KEYCXX) KEYWORD(const_cast , KEYCXX) @@ -278,7 +278,7 @@ KEYWORD(delete , KEYCXX) KEYWORD(dynamic_cast , KEYCXX) KEYWORD(explicit , KEYCXX) KEYWORD(export , KEYCXX) -KEYWORD(false , BOOLSUPPORT|KEYALTIVEC) +KEYWORD(false , BOOLSUPPORT) KEYWORD(friend , KEYCXX) KEYWORD(mutable , KEYCXX) KEYWORD(namespace , KEYCXX) @@ -292,7 +292,7 @@ KEYWORD(static_cast , KEYCXX) KEYWORD(template , KEYCXX) KEYWORD(this , KEYCXX) KEYWORD(throw , KEYCXX) -KEYWORD(true , BOOLSUPPORT|KEYALTIVEC) +KEYWORD(true , BOOLSUPPORT) KEYWORD(try , KEYCXX) KEYWORD(typename , KEYCXX) KEYWORD(typeid , KEYCXX) @@ -349,7 +349,10 @@ KEYWORD(__PRETTY_FUNCTION__ , KEYALL) KEYWORD(typeof , KEYGNU) // MS Extensions +KEYWORD(__FUNCDNAME__ , KEYMS) KEYWORD(L__FUNCTION__ , KEYMS) +KEYWORD(__is_interface_class , KEYMS) +KEYWORD(__is_sealed , KEYMS) // GNU and MS Type Traits KEYWORD(__has_nothrow_assign , KEYCXX) @@ -370,7 +373,6 @@ 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 @@ -509,6 +511,8 @@ ALIAS("__volatile__" , volatile , KEYALL) // Microsoft extensions which should be disabled in strict conformance mode KEYWORD(__ptr64 , KEYMS) KEYWORD(__ptr32 , KEYMS) +KEYWORD(__sptr , KEYMS) +KEYWORD(__uptr , KEYMS) KEYWORD(__w64 , KEYMS) KEYWORD(__uuidof , KEYMS | KEYBORLAND) KEYWORD(__try , KEYMS | KEYBORLAND) @@ -524,6 +528,7 @@ KEYWORD(__interface , KEYMS) ALIAS("__int8" , char , KEYMS) ALIAS("__int16" , short , KEYMS) ALIAS("__int32" , int , KEYMS) +ALIAS("__wchar_t" , wchar_t , KEYMS) ALIAS("_asm" , asm , KEYMS) ALIAS("_alignof" , __alignof , KEYMS) ALIAS("__builtin_alignof", __alignof , KEYMS) @@ -539,6 +544,7 @@ ALIAS("_declspec" , __declspec , KEYMS) ALIAS("_pascal" , __pascal , KEYBORLAND) // Clang Extensions. +KEYWORD(__builtin_convertvector , KEYALL) ALIAS("__char16_t" , char16_t , KEYCXX) ALIAS("__char32_t" , char32_t , KEYCXX) @@ -661,6 +667,9 @@ ANNOTATION(pragma_opencl_extension) ANNOTATION(pragma_openmp) ANNOTATION(pragma_openmp_end) +// Annotation for module import translated from #include etc. +ANNOTATION(module_include) + #undef ANNOTATION #undef TESTING_KEYWORD #undef OBJC2_AT_KEYWORD diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h b/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h index 1645796..fc53527 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TypeTraits.h @@ -57,6 +57,7 @@ namespace clang { UTT_IsReference, UTT_IsRvalueReference, UTT_IsScalar, + UTT_IsSealed, UTT_IsSigned, UTT_IsStandardLayout, UTT_IsTrivial, diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Visibility.h b/contrib/llvm/tools/clang/include/clang/Basic/Visibility.h index b623b94..6ac52ed 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Visibility.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Visibility.h @@ -49,7 +49,7 @@ inline Visibility minVisibility(Visibility L, Visibility R) { } class LinkageInfo { - uint8_t linkage_ : 2; + uint8_t linkage_ : 3; uint8_t visibility_ : 2; uint8_t explicit_ : 1; @@ -89,6 +89,20 @@ public: mergeLinkage(other.getLinkage()); } + void mergeExternalVisibility(Linkage L) { + Linkage ThisL = getLinkage(); + if (!isExternallyVisible(L)) { + if (ThisL == VisibleNoLinkage) + ThisL = NoLinkage; + else if (ThisL == ExternalLinkage) + ThisL = UniqueExternalLinkage; + } + setLinkage(ThisL); + } + void mergeExternalVisibility(LinkageInfo Other) { + mergeExternalVisibility(Other.getLinkage()); + } + /// Merge in the visibility 'newVis'. void mergeVisibility(Visibility newVis, bool newExplicit) { Visibility oldVis = getVisibility(); 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 77bc797..b918459 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td @@ -18,31 +18,58 @@ def OP_NONE : Op; def OP_UNAVAILABLE : Op; def OP_ADD : Op; def OP_ADDL : Op; +def OP_ADDLHi : Op; def OP_ADDW : Op; +def OP_ADDWHi : Op; def OP_SUB : Op; def OP_SUBL : Op; +def OP_SUBLHi : Op; def OP_SUBW : Op; +def OP_SUBWHi : Op; def OP_MUL : Op; def OP_MLA : Op; def OP_MLAL : Op; +def OP_MULLHi : Op; +def OP_MULLHi_N : Op; +def OP_MLALHi : Op; +def OP_MLALHi_N : Op; def OP_MLS : Op; def OP_MLSL : Op; +def OP_MLSLHi : Op; +def OP_MLSLHi_N : Op; def OP_MUL_N : Op; def OP_MLA_N : Op; def OP_MLS_N : Op; +def OP_FMLA_N : Op; +def OP_FMLS_N : Op; def OP_MLAL_N : Op; def OP_MLSL_N : Op; def OP_MUL_LN: Op; +def OP_MULX_LN: Op; def OP_MULL_LN : Op; +def OP_MULLHi_LN : Op; def OP_MLA_LN: Op; def OP_MLS_LN: Op; def OP_MLAL_LN : Op; +def OP_MLALHi_LN : Op; def OP_MLSL_LN : Op; +def OP_MLSLHi_LN : Op; def OP_QDMULL_LN : Op; +def OP_QDMULLHi_LN : Op; def OP_QDMLAL_LN : Op; +def OP_QDMLALHi_LN : Op; def OP_QDMLSL_LN : Op; +def OP_QDMLSLHi_LN : Op; def OP_QDMULH_LN : Op; def OP_QRDMULH_LN : Op; +def OP_FMS_LN : Op; +def OP_FMS_LNQ : Op; +def OP_TRN1 : Op; +def OP_ZIP1 : Op; +def OP_UZP1 : Op; +def OP_TRN2 : Op; +def OP_ZIP2 : Op; +def OP_UZP2 : Op; def OP_EQ : Op; def OP_GE : Op; def OP_LE : Op; @@ -65,10 +92,49 @@ def OP_SEL : Op; def OP_REV64 : Op; def OP_REV32 : Op; def OP_REV16 : Op; +def OP_XTN : Op; +def OP_SQXTUN : Op; +def OP_QXTN : Op; +def OP_VCVT_NA_HI : Op; +def OP_VCVT_EX_HI : Op; +def OP_VCVTX_HI : Op; def OP_REINT : Op; +def OP_ADDHNHi : Op; +def OP_RADDHNHi : Op; +def OP_SUBHNHi : Op; +def OP_RSUBHNHi : Op; def OP_ABDL : Op; +def OP_ABDLHi : Op; def OP_ABA : Op; def OP_ABAL : Op; +def OP_ABALHi : Op; +def OP_QDMULLHi : Op; +def OP_QDMULLHi_N : Op; +def OP_QDMLALHi : Op; +def OP_QDMLALHi_N : Op; +def OP_QDMLSLHi : Op; +def OP_QDMLSLHi_N : Op; +def OP_DIV : Op; +def OP_LONG_HI : Op; +def OP_NARROW_HI : Op; +def OP_MOVL_HI : Op; +def OP_COPY_LN : Op; +def OP_COPYQ_LN : Op; +def OP_COPY_LNQ : Op; +def OP_SCALAR_MUL_LN : Op; +def OP_SCALAR_MUL_LNQ : Op; +def OP_SCALAR_MULX_LN : Op; +def OP_SCALAR_MULX_LNQ : Op; +def OP_SCALAR_VMULX_LN : Op; +def OP_SCALAR_VMULX_LNQ : Op; +def OP_SCALAR_QDMULL_LN : Op; +def OP_SCALAR_QDMULL_LNQ : Op; +def OP_SCALAR_QDMULH_LN : Op; +def OP_SCALAR_QDMULH_LNQ : Op; +def OP_SCALAR_QRDMULH_LN : Op; +def OP_SCALAR_QRDMULH_LNQ : Op; +def OP_SCALAR_GET_LN : Op; +def OP_SCALAR_SET_LN : Op; class Inst <string n, string p, string t, Op o> { string Name = n; @@ -76,7 +142,11 @@ class Inst <string n, string p, string t, Op o> { string Types = t; Op Operand = o; bit isShift = 0; + bit isScalarShift = 0; + bit isScalarNarrowShift = 0; bit isVCVT_N = 0; + bit isA64 = 0; + bit isCrypto = 0; // Certain intrinsics have different names than their representative // instructions. This field allows us to handle this correctly when we @@ -123,18 +193,29 @@ class NoTestOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} // x: signed integer (int/float args) // u: unsigned integer (int/float args) // f: float (int args) +// F: double (int args) // d: default // g: default, ignore 'Q' size modifier. +// j: default, force 'Q' size modifier. // w: double width elements, same num elts // n: double width elements, half num elts // h: half width elements, double num elts +// q: half width elements, quad num elts // e: half width elements, double num elts, unsigned +// m: half width elements, same num elts // i: constant int // l: constant uint64 // s: scalar of element type +// z: scalar of half width element type, signed +// r: scalar of double width element type, signed // a: scalar of element type (splat to vector type) +// b: scalar of unsigned integer/long type (int/float args) +// $: scalar of signed integer/long type (int/float args) +// y: scalar of float +// o: scalar of double // k: default elt width, double num elts -// #: array of default vectors +// 2,3,4: array of default vectors +// B,C,D: array of default elts, force 'Q' size modifier. // p: pointer type // c: const pointer type @@ -145,10 +226,13 @@ class NoTestOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} // l: long // f: float // h: half-float +// d: double // size modifiers: +// S: scalar, only used for function mangling. // U: unsigned // Q: 128b +// H: 128b without mangling 'q' // P: polynomial //////////////////////////////////////////////////////////////////////////////// @@ -206,7 +290,7 @@ let InstName = "vacgt" in { def VCAGT : IInst<"vcagt", "udd", "fQf">; def VCALT : IInst<"vcalt", "udd", "fQf">; } -def VTST : WInst<"vtst", "udd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc">; +def VTST : WInst<"vtst", "udd", "csiUcUsUiPcPsQcQsQiQUcQUsQUiQPcQPs">; //////////////////////////////////////////////////////////////////////////////// // E.3.5 Absolute Difference @@ -452,3 +536,803 @@ def VREINTERPRET // Vector fused multiply-add operations def VFMA : SInst<"vfma", "dddd", "fQf">; + +//////////////////////////////////////////////////////////////////////////////// +// AArch64 Intrinsics + +let isA64 = 1 in { + +//////////////////////////////////////////////////////////////////////////////// +// Load/Store +// With additional QUl, Ql, d, Qd, Pl, QPl type. +def LD1 : WInst<"vld1", "dc", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">; +def LD2 : WInst<"vld2", "2c", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">; +def LD3 : WInst<"vld3", "3c", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">; +def LD4 : WInst<"vld4", "4c", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">; +def ST1 : WInst<"vst1", "vpd", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">; +def ST2 : WInst<"vst2", "vp2", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">; +def ST3 : WInst<"vst3", "vp3", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">; +def ST4 : WInst<"vst4", "vp4", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">; + +def LD1_X2 : WInst<"vld1_x2", "2c", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def LD3_x3 : WInst<"vld1_x3", "3c", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def LD4_x4 : WInst<"vld1_x4", "4c", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; + +def ST1_X2 : WInst<"vst1_x2", "vp2", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def ST1_X3 : WInst<"vst1_x3", "vp3", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def ST1_X4 : WInst<"vst1_x4", "vp4", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; + +// With additional QUl, Ql, d, Qd, Pl, QPl type. +def LD1_LANE : WInst<"vld1_lane", "dcdi", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def LD2_LANE : WInst<"vld2_lane", "2c2i", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def LD3_LANE : WInst<"vld3_lane", "3c3i", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def LD4_LANE : WInst<"vld4_lane", "4c4i", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def ST1_LANE : WInst<"vst1_lane", "vpdi", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def ST2_LANE : WInst<"vst2_lane", "vp2i", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def ST3_LANE : WInst<"vst3_lane", "vp3i", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def ST4_LANE : WInst<"vst4_lane", "vp4i", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; + +def LD1_DUP : WInst<"vld1_dup", "dc", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def LD2_DUP : WInst<"vld2_dup", "2c", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def LD3_DUP : WInst<"vld3_dup", "3c", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; +def LD4_DUP : WInst<"vld4_dup", "4c", + "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">; + +//////////////////////////////////////////////////////////////////////////////// +// Addition +// With additional d, Qd type. +def ADD : IOpInst<"vadd", "ddd", "csilfdUcUsUiUlQcQsQiQlQfQUcQUsQUiQUlQd", + OP_ADD>; + +//////////////////////////////////////////////////////////////////////////////// +// Subtraction +// With additional Qd type. +def SUB : IOpInst<"vsub", "ddd", "csildfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUlQd", + OP_SUB>; + +//////////////////////////////////////////////////////////////////////////////// +// Multiplication +// With additional Qd type. +def MUL : IOpInst<"vmul", "ddd", "csifdUcUsUiQcQsQiQfQUcQUsQUiQd", OP_MUL>; +def MLA : IOpInst<"vmla", "dddd", "csifdUcUsUiQcQsQiQfQUcQUsQUiQd", OP_MLA>; +def MLS : IOpInst<"vmls", "dddd", "csifdUcUsUiQcQsQiQfQUcQUsQUiQd", OP_MLS>; + +//////////////////////////////////////////////////////////////////////////////// +// Multiplication Extended +def MULX : SInst<"vmulx", "ddd", "fdQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Division +def FDIV : IOpInst<"vdiv", "ddd", "fdQfQd", OP_DIV>; + +//////////////////////////////////////////////////////////////////////////////// +// Vector fused multiply-add operations +// With additional d, Qd type. +def FMLA : SInst<"vfma", "dddd", "fdQfQd">; +def FMLS : SInst<"vfms", "dddd", "fdQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// MUL, FMA, FMS definitions with scalar argument +def VMUL_N_A64 : IOpInst<"vmul_n", "dds", "Qd", OP_MUL_N>; +def FMLA_N : SOpInst<"vfma_n", "ddds", "fQf", OP_FMLA_N>; +def FMLS_N : SOpInst<"vfms_n", "ddds", "fQf", OP_FMLS_N>; + +//////////////////////////////////////////////////////////////////////////////// +// Logical operations +// With additional Qd, Ql, QPl type. +def BSL : SInst<"vbsl", "dudd", + "csilUcUsUiUlfdPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPsQdPlQPl">; + +//////////////////////////////////////////////////////////////////////////////// +// Absolute Difference +// With additional Qd type. +def ABD : SInst<"vabd", "ddd", "csiUcUsUifdQcQsQiQUcQUsQUiQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// saturating absolute/negate +// With additional Qd/Ql type. +def ABS : SInst<"vabs", "dd", "csilfdQcQsQiQfQlQd">; +def QABS : SInst<"vqabs", "dd", "csilQcQsQiQl">; +def NEG : SOpInst<"vneg", "dd", "csilfdQcQsQiQfQdQl", OP_NEG>; +def QNEG : SInst<"vqneg", "dd", "csilQcQsQiQl">; + +//////////////////////////////////////////////////////////////////////////////// +// Signed Saturating Accumulated of Unsigned Value +def SUQADD : SInst<"vuqadd", "ddd", "csilQcQsQiQl">; + +//////////////////////////////////////////////////////////////////////////////// +// Unsigned Saturating Accumulated of Signed Value +def USQADD : SInst<"vsqadd", "ddd", "UcUsUiUlQUcQUsQUiQUl">; + +//////////////////////////////////////////////////////////////////////////////// +// Reciprocal/Sqrt +// With additional d, Qd type. +def FRECPS : IInst<"vrecps", "ddd", "fdQfQd">; +def FRSQRTS : IInst<"vrsqrts", "ddd", "fdQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// bitwise reverse +def RBIT : IInst<"vrbit", "dd", "cUcPcQcQUcQPc">; + +//////////////////////////////////////////////////////////////////////////////// +// Integer extract and narrow to high +def XTN2 : SOpInst<"vmovn_high", "qhk", "silUsUiUl", OP_XTN>; + +//////////////////////////////////////////////////////////////////////////////// +// Signed integer saturating extract and unsigned narrow to high +def SQXTUN2 : SOpInst<"vqmovun_high", "qhk", "sil", OP_SQXTUN>; + +//////////////////////////////////////////////////////////////////////////////// +// Integer saturating extract and narrow to high +def QXTN2 : SOpInst<"vqmovn_high", "qhk", "silUsUiUl", OP_QXTN>; + +//////////////////////////////////////////////////////////////////////////////// +// Converting vectors +def VCVT_HIGH_F16 : SOpInst<"vcvt_high_f16", "qhj", "f", OP_VCVT_NA_HI>; +def VCVT_HIGH_F32_F16 : SOpInst<"vcvt_high_f32", "wk", "h", OP_VCVT_EX_HI>; +def VCVT_F32_F64 : SInst<"vcvt_f32_f64", "fj", "d">; +def VCVT_HIGH_F32_F64 : SOpInst<"vcvt_high_f32", "qfj", "d", OP_VCVT_NA_HI>; +def VCVT_F64_F32 : SInst<"vcvt_f64_f32", "wd", "f">; +def VCVT_F64 : SInst<"vcvt_f64", "Fd", "lUlQlQUl">; +def VCVT_HIGH_F64_F32 : SOpInst<"vcvt_high_f64", "wj", "f", OP_VCVT_EX_HI>; +def VCVTX_F32_F64 : SInst<"vcvtx_f32", "fj", "d">; +def VCVTX_HIGH_F32_F64 : SOpInst<"vcvtx_high_f32", "qfj", "d", OP_VCVTX_HI>; +def FRINTN : SInst<"vrndn", "dd", "fdQfQd">; +def FRINTA : SInst<"vrnda", "dd", "fdQfQd">; +def FRINTP : SInst<"vrndp", "dd", "fdQfQd">; +def FRINTM : SInst<"vrndm", "dd", "fdQfQd">; +def FRINTX : SInst<"vrndx", "dd", "fdQfQd">; +def FRINTZ : SInst<"vrnd", "dd", "fdQfQd">; +def FRINTI : SInst<"vrndi", "dd", "fdQfQd">; +def VCVT_S64 : SInst<"vcvt_s64", "xd", "dQd">; +def VCVT_U64 : SInst<"vcvt_u64", "ud", "dQd">; +def FCVTNS_S32 : SInst<"vcvtn_s32", "xd", "fQf">; +def FCVTNS_S64 : SInst<"vcvtn_s64", "xd", "dQd">; +def FCVTNU_S32 : SInst<"vcvtn_u32", "ud", "fQf">; +def FCVTNU_S64 : SInst<"vcvtn_u64", "ud", "dQd">; +def FCVTPS_S32 : SInst<"vcvtp_s32", "xd", "fQf">; +def FCVTPS_S64 : SInst<"vcvtp_s64", "xd", "dQd">; +def FCVTPU_S32 : SInst<"vcvtp_u32", "ud", "fQf">; +def FCVTPU_S64 : SInst<"vcvtp_u64", "ud", "dQd">; +def FCVTMS_S32 : SInst<"vcvtm_s32", "xd", "fQf">; +def FCVTMS_S64 : SInst<"vcvtm_s64", "xd", "dQd">; +def FCVTMU_S32 : SInst<"vcvtm_u32", "ud", "fQf">; +def FCVTMU_S64 : SInst<"vcvtm_u64", "ud", "dQd">; +def FCVTAS_S32 : SInst<"vcvta_s32", "xd", "fQf">; +def FCVTAS_S64 : SInst<"vcvta_s64", "xd", "dQd">; +def FCVTAU_S32 : SInst<"vcvta_u32", "ud", "fQf">; +def FCVTAU_S64 : SInst<"vcvta_u64", "ud", "dQd">; +def FRECPE : SInst<"vrecpe", "dd", "fdUiQfQUiQd">; +def FRSQRTE : SInst<"vrsqrte", "dd", "fdUiQfQUiQd">; +def FSQRT : SInst<"vsqrt", "dd", "fdQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Comparison +// With additional Qd, Ql, QPl type. +def FCAGE : IInst<"vcage", "udd", "fdQfQd">; +def FCAGT : IInst<"vcagt", "udd", "fdQfQd">; +def FCALE : IInst<"vcale", "udd", "fdQfQd">; +def FCALT : IInst<"vcalt", "udd", "fdQfQd">; +// With additional Ql, QUl, Qd types. +def CMTST : WInst<"vtst", "udd", + "csiUcUsUiPcPsQcQsQiQUcQUsQUiQPcQPslUlQlQUlPlQPl">; +// With additional l, Ul,d, Qd, Ql, QUl, Qd types. +def CFMEQ : SOpInst<"vceq", "udd", + "csilfUcUsUiUlPcQcdQdQsQiQfQUcQUsQUiQUlQlQPcPlQPl", OP_EQ>; +def CFMGE : SOpInst<"vcge", "udd", + "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUldQd", OP_GE>; +def CFMLE : SOpInst<"vcle", "udd", + "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUldQd", OP_LE>; +def CFMGT : SOpInst<"vcgt", "udd", + "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUldQd", OP_GT>; +def CFMLT : SOpInst<"vclt", "udd", + "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUldQd", OP_LT>; + +def CMEQ : SInst<"vceqz", "ud", + "csilfUcUsUiUlPcPsPlQcQsQiQlQfQUcQUsQUiQUlQPcQPsdQdQPl">; +def CMGE : SInst<"vcgez", "ud", "csilfdQcQsQiQlQfQd">; +def CMLE : SInst<"vclez", "ud", "csilfdQcQsQiQlQfQd">; +def CMGT : SInst<"vcgtz", "ud", "csilfdQcQsQiQlQfQd">; +def CMLT : SInst<"vcltz", "ud", "csilfdQcQsQiQlQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Max/Min Integer +// With additional Qd type. +def MAX : SInst<"vmax", "ddd", "csiUcUsUifdQcQsQiQUcQUsQUiQfQd">; +def MIN : SInst<"vmin", "ddd", "csiUcUsUifdQcQsQiQUcQUsQUiQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// MaxNum/MinNum Floating Point +def FMAXNM : SInst<"vmaxnm", "ddd", "fdQfQd">; +def FMINNM : SInst<"vminnm", "ddd", "fdQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Pairwise Max/Min +// With additional Qc Qs Qi QUc QUs QUi Qf Qd types. +def MAXP : SInst<"vpmax", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQfQd">; +def MINP : SInst<"vpmin", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Pairwise MaxNum/MinNum Floating Point +def FMAXNMP : SInst<"vpmaxnm", "ddd", "fQfQd">; +def FMINNMP : SInst<"vpminnm", "ddd", "fQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Pairwise Addition +// With additional Qc Qs Qi QUc QUs QUi Qf Qd types. +def ADDP : IInst<"vpadd", "ddd", "csiUcUsUifQcQsQiQlQUcQUsQUiQUlQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Shifts by constant +let isShift = 1 in { +// Left shift long high +def SHLL_HIGH_N : SOpInst<"vshll_high_n", "ndi", "HcHsHiHUcHUsHUi", + OP_LONG_HI>; + +//////////////////////////////////////////////////////////////////////////////// +// Shifts with insert, with additional Ql, QPl type. +def SRI_N : WInst<"vsri_n", "dddi", + "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPsPlQPl">; +def SLI_N : WInst<"vsli_n", "dddi", + "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPsPlQPl">; + +// Right shift narrow high +def SHRN_HIGH_N : IOpInst<"vshrn_high_n", "hmdi", + "HsHiHlHUsHUiHUl", OP_NARROW_HI>; +def QSHRUN_HIGH_N : SOpInst<"vqshrun_high_n", "hmdi", + "HsHiHl", OP_NARROW_HI>; +def RSHRN_HIGH_N : IOpInst<"vrshrn_high_n", "hmdi", + "HsHiHlHUsHUiHUl", OP_NARROW_HI>; +def QRSHRUN_HIGH_N : SOpInst<"vqrshrun_high_n", "hmdi", + "HsHiHl", OP_NARROW_HI>; +def QSHRN_HIGH_N : SOpInst<"vqshrn_high_n", "hmdi", + "HsHiHlHUsHUiHUl", OP_NARROW_HI>; +def QRSHRN_HIGH_N : SOpInst<"vqrshrn_high_n", "hmdi", + "HsHiHlHUsHUiHUl", OP_NARROW_HI>; +} + +//////////////////////////////////////////////////////////////////////////////// +// Converting vectors +def VMOVL_HIGH : SOpInst<"vmovl_high", "nd", "HcHsHiHUcHUsHUi", OP_MOVL_HI>; + +let isVCVT_N = 1 in { +def CVTF_N_F64 : SInst<"vcvt_n_f64", "Fdi", "lUlQlQUl">; +def FCVTZS_N_S64 : SInst<"vcvt_n_s64", "xdi", "dQd">; +def FCVTZS_N_U64 : SInst<"vcvt_n_u64", "udi", "dQd">; +} + +//////////////////////////////////////////////////////////////////////////////// +// 3VDiff class using high 64-bit in operands +def VADDL_HIGH : SOpInst<"vaddl_high", "wkk", "csiUcUsUi", OP_ADDLHi>; +def VADDW_HIGH : SOpInst<"vaddw_high", "wwk", "csiUcUsUi", OP_ADDWHi>; +def VSUBL_HIGH : SOpInst<"vsubl_high", "wkk", "csiUcUsUi", OP_SUBLHi>; +def VSUBW_HIGH : SOpInst<"vsubw_high", "wwk", "csiUcUsUi", OP_SUBWHi>; + +def VABDL_HIGH : SOpInst<"vabdl_high", "wkk", "csiUcUsUi", OP_ABDLHi>; +def VABAL_HIGH : SOpInst<"vabal_high", "wwkk", "csiUcUsUi", OP_ABALHi>; + +def VMULL_HIGH : SOpInst<"vmull_high", "wkk", "csiUcUsUiPc", OP_MULLHi>; +def VMULL_HIGH_N : SOpInst<"vmull_high_n", "wks", "siUsUi", OP_MULLHi_N>; +def VMLAL_HIGH : SOpInst<"vmlal_high", "wwkk", "csiUcUsUi", OP_MLALHi>; +def VMLAL_HIGH_N : SOpInst<"vmlal_high_n", "wwks", "siUsUi", OP_MLALHi_N>; +def VMLSL_HIGH : SOpInst<"vmlsl_high", "wwkk", "csiUcUsUi", OP_MLSLHi>; +def VMLSL_HIGH_N : SOpInst<"vmlsl_high_n", "wwks", "siUsUi", OP_MLSLHi_N>; + +def VADDHN_HIGH : SOpInst<"vaddhn_high", "qhkk", "silUsUiUl", OP_ADDHNHi>; +def VRADDHN_HIGH : SOpInst<"vraddhn_high", "qhkk", "silUsUiUl", OP_RADDHNHi>; +def VSUBHN_HIGH : SOpInst<"vsubhn_high", "qhkk", "silUsUiUl", OP_SUBHNHi>; +def VRSUBHN_HIGH : SOpInst<"vrsubhn_high", "qhkk", "silUsUiUl", OP_RSUBHNHi>; + +def VQDMULL_HIGH : SOpInst<"vqdmull_high", "wkk", "si", OP_QDMULLHi>; +def VQDMULL_HIGH_N : SOpInst<"vqdmull_high_n", "wks", "si", OP_QDMULLHi_N>; +def VQDMLAL_HIGH : SOpInst<"vqdmlal_high", "wwkk", "si", OP_QDMLALHi>; +def VQDMLAL_HIGH_N : SOpInst<"vqdmlal_high_n", "wwks", "si", OP_QDMLALHi_N>; +def VQDMLSL_HIGH : SOpInst<"vqdmlsl_high", "wwkk", "si", OP_QDMLSLHi>; +def VQDMLSL_HIGH_N : SOpInst<"vqdmlsl_high_n", "wwks", "si", OP_QDMLSLHi_N>; + +//////////////////////////////////////////////////////////////////////////////// +// Extract or insert element from vector +def GET_LANE : IInst<"vget_lane", "sdi", + "csilPcPsUcUsUiUlQcQsQiQlQUcQUsQUiQUlPcPsQPcQPsfdQfQdPlQPl">; +def SET_LANE : IInst<"vset_lane", "dsdi", + "csilPcPsUcUsUiUlQcQsQiQlQUcQUsQUiQUlPcPsQPcQPsfdQfQdPlQPl">; +def COPY_LANE : IOpInst<"vcopy_lane", "ddidi", + "csilPcPsUcUsUiUlPcPsPlfd", OP_COPY_LN>; +def COPYQ_LANE : IOpInst<"vcopy_lane", "ddigi", + "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPYQ_LN>; +def COPY_LANEQ : IOpInst<"vcopy_laneq", "ddiki", + "csilPcPsPlUcUsUiUlfd", OP_COPY_LNQ>; +def COPYQ_LANEQ : IOpInst<"vcopy_laneq", "ddidi", + "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>; + +//////////////////////////////////////////////////////////////////////////////// +// Set all lanes to same value +def VDUP_LANE1: WOpInst<"vdup_lane", "dgi", + "csilPcPsUcUsUiUlhfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl", + OP_DUP_LN>; +def VDUP_LANE2: WOpInst<"vdup_laneq", "dki", + "csilPcPsUcUsUiUlhfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl", + OP_DUP_LN>; +def DUP_N : WOpInst<"vdup_n", "ds", + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUldQdPlQPl", + OP_DUP>; +def MOV_N : WOpInst<"vmov_n", "ds", + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUldQd", + OP_DUP>; + +//////////////////////////////////////////////////////////////////////////////// +// Combining vectors, with additional Pl +def COMBINE : NoTestOpInst<"vcombine", "kdd", "csilhfdUcUsUiUlPcPsPl", OP_CONC>; + +//////////////////////////////////////////////////////////////////////////////// +//Initialize a vector from bit pattern, with additional Pl +def CREATE : NoTestOpInst<"vcreate", "dl", "csihfdUcUsUiUlPcPslPl", OP_CAST>; + +//////////////////////////////////////////////////////////////////////////////// + +def VMLA_LANEQ : IOpInst<"vmla_laneq", "dddji", + "siUsUifQsQiQUsQUiQf", OP_MLA_LN>; +def VMLS_LANEQ : IOpInst<"vmls_laneq", "dddji", + "siUsUifQsQiQUsQUiQf", OP_MLS_LN>; + +def VFMA_LANE : IInst<"vfma_lane", "dddgi", "fdQfQd">; +def VFMA_LANEQ : IInst<"vfma_laneq", "dddji", "fdQfQd">; +def VFMS_LANE : IOpInst<"vfms_lane", "dddgi", "fdQfQd", OP_FMS_LN>; +def VFMS_LANEQ : IOpInst<"vfms_laneq", "dddji", "fdQfQd", OP_FMS_LNQ>; + +def VMLAL_LANEQ : SOpInst<"vmlal_laneq", "wwdki", "siUsUi", OP_MLAL_LN>; +def VMLAL_HIGH_LANE : SOpInst<"vmlal_high_lane", "wwkdi", "siUsUi", + OP_MLALHi_LN>; +def VMLAL_HIGH_LANEQ : SOpInst<"vmlal_high_laneq", "wwkki", "siUsUi", + OP_MLALHi_LN>; +def VMLSL_LANEQ : SOpInst<"vmlsl_laneq", "wwdki", "siUsUi", OP_MLSL_LN>; +def VMLSL_HIGH_LANE : SOpInst<"vmlsl_high_lane", "wwkdi", "siUsUi", + OP_MLSLHi_LN>; +def VMLSL_HIGH_LANEQ : SOpInst<"vmlsl_high_laneq", "wwkki", "siUsUi", + OP_MLSLHi_LN>; + +def VQDMLAL_LANEQ : SOpInst<"vqdmlal_laneq", "wwdki", "si", OP_QDMLAL_LN>; +def VQDMLAL_HIGH_LANE : SOpInst<"vqdmlal_high_lane", "wwkdi", "si", + OP_QDMLALHi_LN>; +def VQDMLAL_HIGH_LANEQ : SOpInst<"vqdmlal_high_laneq", "wwkki", "si", + OP_QDMLALHi_LN>; +def VQDMLSL_LANEQ : SOpInst<"vqdmlsl_laneq", "wwdki", "si", OP_QDMLSL_LN>; +def VQDMLSL_HIGH_LANE : SOpInst<"vqdmlsl_high_lane", "wwkdi", "si", + OP_QDMLSLHi_LN>; +def VQDMLSL_HIGH_LANEQ : SOpInst<"vqdmlsl_high_laneq", "wwkki", "si", + OP_QDMLSLHi_LN>; + +// Newly add double parameter for vmul_lane in aarch64 +// Note: d type is handled by SCALAR_VMUL_LANE +def VMUL_LANE_A64 : IOpInst<"vmul_lane", "ddgi", "Qd", OP_MUL_LN>; + +// Note: d type is handled by SCALAR_VMUL_LANEQ +def VMUL_LANEQ : IOpInst<"vmul_laneq", "ddji", + "sifUsUiQsQiQfQUsQUiQfQd", OP_MUL_LN>; +def VMULL_LANEQ : SOpInst<"vmull_laneq", "wdki", "siUsUi", OP_MULL_LN>; +def VMULL_HIGH_LANE : SOpInst<"vmull_high_lane", "wkdi", "siUsUi", + OP_MULLHi_LN>; +def VMULL_HIGH_LANEQ : SOpInst<"vmull_high_laneq", "wkki", "siUsUi", + OP_MULLHi_LN>; + +def VQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "wdki", "si", OP_QDMULL_LN>; +def VQDMULL_HIGH_LANE : SOpInst<"vqdmull_high_lane", "wkdi", "si", + OP_QDMULLHi_LN>; +def VQDMULL_HIGH_LANEQ : SOpInst<"vqdmull_high_laneq", "wkki", "si", + OP_QDMULLHi_LN>; + +def VQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "ddji", "siQsQi", OP_QDMULH_LN>; +def VQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ddji", "siQsQi", OP_QRDMULH_LN>; + +// Note: d type implemented by SCALAR_VMULX_LANE +def VMULX_LANE : IOpInst<"vmulx_lane", "ddgi", "fQfQd", OP_MULX_LN>; +// Note: d type is implemented by SCALAR_VMULX_LANEQ +def VMULX_LANEQ : IOpInst<"vmulx_laneq", "ddji", "fQfQd", OP_MULX_LN>; + +//////////////////////////////////////////////////////////////////////////////// +// Across vectors class +def VADDLV : SInst<"vaddlv", "rd", "csiUcUsUiQcQsQiQUcQUsQUi">; +def VMAXV : SInst<"vmaxv", "sd", "csifUcUsUiQcQsQiQUcQUsQUiQfQd">; +def VMINV : SInst<"vminv", "sd", "csifUcUsUiQcQsQiQUcQUsQUiQfQd">; +def VADDV : SInst<"vaddv", "sd", "csifUcUsUiQcQsQiQUcQUsQUiQfQdQlQUl">; +def FMAXNMV : SInst<"vmaxnmv", "sd", "fQfQd">; +def FMINNMV : SInst<"vminnmv", "sd", "fQfQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Newly added Vector Extract for f64 +def VEXT_A64 : WInst<"vext", "dddi", + "cUcPcsUsPsiUilUlfdQcQUcQPcQsQUsQPsQiQUiQlQUlQfQdPlQPl">; + +//////////////////////////////////////////////////////////////////////////////// +// Crypto +let isCrypto = 1 in { +def AESE : SInst<"vaese", "ddd", "QUc">; +def AESD : SInst<"vaesd", "ddd", "QUc">; +def AESMC : SInst<"vaesmc", "dd", "QUc">; +def AESIMC : SInst<"vaesimc", "dd", "QUc">; + +def SHA1H : SInst<"vsha1h", "ss", "Ui">; +def SHA1SU1 : SInst<"vsha1su1", "ddd", "QUi">; +def SHA256SU0 : SInst<"vsha256su0", "ddd", "QUi">; + +def SHA1C : SInst<"vsha1c", "ddsd", "QUi">; +def SHA1P : SInst<"vsha1p", "ddsd", "QUi">; +def SHA1M : SInst<"vsha1m", "ddsd", "QUi">; +def SHA1SU0 : SInst<"vsha1su0", "dddd", "QUi">; +def SHA256H : SInst<"vsha256h", "dddd", "QUi">; +def SHA256H2 : SInst<"vsha256h2", "dddd", "QUi">; +def SHA256SU1 : SInst<"vsha256su1", "dddd", "QUi">; +} + +//////////////////////////////////////////////////////////////////////////////// +// Permutation +def VTRN1 : SOpInst<"vtrn1", "ddd", + "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_TRN1>; +def VZIP1 : SOpInst<"vzip1", "ddd", + "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_ZIP1>; +def VUZP1 : SOpInst<"vuzp1", "ddd", + "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_UZP1>; +def VTRN2 : SOpInst<"vtrn2", "ddd", + "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_TRN2>; +def VZIP2 : SOpInst<"vzip2", "ddd", + "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_ZIP2>; +def VUZP2 : SOpInst<"vuzp2", "ddd", + "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_UZP2>; + +//////////////////////////////////////////////////////////////////////////////// +// Table lookup +let InstName = "vtbl" in { +def VQTBL1_A64 : WInst<"vqtbl1", "djt", "UccPcQUcQcQPc">; +def VQTBL2_A64 : WInst<"vqtbl2", "dBt", "UccPcQUcQcQPc">; +def VQTBL3_A64 : WInst<"vqtbl3", "dCt", "UccPcQUcQcQPc">; +def VQTBL4_A64 : WInst<"vqtbl4", "dDt", "UccPcQUcQcQPc">; +} +let InstName = "vtbx" in { +def VQTBX1_A64 : WInst<"vqtbx1", "ddjt", "UccPcQUcQcQPc">; +def VQTBX2_A64 : WInst<"vqtbx2", "ddBt", "UccPcQUcQcQPc">; +def VQTBX3_A64 : WInst<"vqtbx3", "ddCt", "UccPcQUcQcQPc">; +def VQTBX4_A64 : WInst<"vqtbx4", "ddDt", "UccPcQUcQcQPc">; +} + +//////////////////////////////////////////////////////////////////////////////// +// Vector reinterpret cast operations +// With additional d, Qd, pl, Qpl types +def REINTERPRET + : NoTestOpInst<"vreinterpret", "dd", + "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPl", OP_REINT>; + + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Intrinsics +// Scalar Arithmetic + +// Scalar Addition +def SCALAR_ADD : SInst<"vadd", "sss", "SlSUl">; +// Scalar Saturating Add +def SCALAR_QADD : SInst<"vqadd", "sss", "ScSsSiSlSUcSUsSUiSUl">; + +// Scalar Subtraction +def SCALAR_SUB : SInst<"vsub", "sss", "SlSUl">; +// Scalar Saturating Sub +def SCALAR_QSUB : SInst<"vqsub", "sss", "ScSsSiSlSUcSUsSUiSUl">; + +let InstName = "vmov" in { +def VGET_HIGH_A64 : NoTestOpInst<"vget_high", "dk", "csilhfdUcUsUiUlPcPsPl", + OP_HI>; +def VGET_LOW_A64 : NoTestOpInst<"vget_low", "dk", "csilhfdUcUsUiUlPcPsPl", + OP_LO>; +} + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Shift +// Scalar Shift Left +def SCALAR_SHL: SInst<"vshl", "sss", "SlSUl">; +// Scalar Saturating Shift Left +def SCALAR_QSHL: SInst<"vqshl", "sss", "ScSsSiSlSUcSUsSUiSUl">; +// Scalar Saturating Rounding Shift Left +def SCALAR_QRSHL: SInst<"vqrshl", "sss", "ScSsSiSlSUcSUsSUiSUl">; +// Scalar Shift Rouding Left +def SCALAR_RSHL: SInst<"vrshl", "sss", "SlSUl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Shift (Immediate) +let isScalarShift = 1 in { +// Signed/Unsigned Shift Right (Immediate) +def SCALAR_SSHR_N: SInst<"vshr_n", "ssi", "SlSUl">; +// Signed/Unsigned Rounding Shift Right (Immediate) +def SCALAR_SRSHR_N: SInst<"vrshr_n", "ssi", "SlSUl">; + +// Signed/Unsigned Shift Right and Accumulate (Immediate) +def SCALAR_SSRA_N: SInst<"vsra_n", "sssi", "SlSUl">; +// Signed/Unsigned Rounding Shift Right and Accumulate (Immediate) +def SCALAR_SRSRA_N: SInst<"vrsra_n", "sssi", "SlSUl">; + +// Shift Left (Immediate) +def SCALAR_SHL_N: SInst<"vshl_n", "ssi", "SlSUl">; +// Signed/Unsigned Saturating Shift Left (Immediate) +def SCALAR_SQSHL_N: SInst<"vqshl_n", "ssi", "ScSsSiSlSUcSUsSUiSUl">; +// Signed Saturating Shift Left Unsigned (Immediate) +def SCALAR_SQSHLU_N: SInst<"vqshlu_n", "ssi", "ScSsSiSl">; + +// Shift Right And Insert (Immediate) +def SCALAR_SRI_N: SInst<"vsri_n", "sssi", "SlSUl">; +// Shift Left And Insert (Immediate) +def SCALAR_SLI_N: SInst<"vsli_n", "sssi", "SlSUl">; + +let isScalarNarrowShift = 1 in { + // Signed/Unsigned Saturating Shift Right Narrow (Immediate) + def SCALAR_SQSHRN_N: SInst<"vqshrn_n", "zsi", "SsSiSlSUsSUiSUl">; + // Signed/Unsigned Saturating Rounded Shift Right Narrow (Immediate) + def SCALAR_SQRSHRN_N: SInst<"vqrshrn_n", "zsi", "SsSiSlSUsSUiSUl">; + // Signed Saturating Shift Right Unsigned Narrow (Immediate) + def SCALAR_SQSHRUN_N: SInst<"vqshrun_n", "zsi", "SsSiSl">; + // Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate) + def SCALAR_SQRSHRUN_N: SInst<"vqrshrun_n", "zsi", "SsSiSl">; +} + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Signed/Unsigned Fixed-point Convert To Floating-Point (Immediate) +def SCALAR_SCVTF_N_F32: SInst<"vcvt_n_f32", "ysi", "SiSUi">; +def SCALAR_SCVTF_N_F64: SInst<"vcvt_n_f64", "osi", "SlSUl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Convert To Signed/Unsigned Fixed-point (Immediate) +def SCALAR_FCVTZS_N_S32 : SInst<"vcvt_n_s32", "$si", "Sf">; +def SCALAR_FCVTZU_N_U32 : SInst<"vcvt_n_u32", "bsi", "Sf">; +def SCALAR_FCVTZS_N_S64 : SInst<"vcvt_n_s64", "$si", "Sd">; +def SCALAR_FCVTZU_N_U64 : SInst<"vcvt_n_u64", "bsi", "Sd">; +} + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Reduce Pairwise Addition (Scalar and Floating Point) +def SCALAR_ADDP : SInst<"vpadd", "sd", "SfSHlSHdSHUl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Reduce Floating Point Pairwise Max/Min +def SCALAR_FMAXP : SInst<"vpmax", "sd", "SfSQd">; + +def SCALAR_FMINP : SInst<"vpmin", "sd", "SfSQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Reduce Floating Point Pairwise maxNum/minNum +def SCALAR_FMAXNMP : SInst<"vpmaxnm", "sd", "SfSQd">; +def SCALAR_FMINNMP : SInst<"vpminnm", "sd", "SfSQd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Integer Saturating Doubling Multiply Half High +def SCALAR_SQDMULH : SInst<"vqdmulh", "sss", "SsSi">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Integer Saturating Rounding Doubling Multiply Half High +def SCALAR_SQRDMULH : SInst<"vqrdmulh", "sss", "SsSi">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Multiply Extended +def SCALAR_FMULX : IInst<"vmulx", "sss", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Reciprocal Step +def SCALAR_FRECPS : IInst<"vrecps", "sss", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Reciprocal Square Root Step +def SCALAR_FRSQRTS : IInst<"vrsqrts", "sss", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Signed Integer Convert To Floating-point +def SCALAR_SCVTFS : SInst<"vcvt_f32", "ys", "Si">; +def SCALAR_SCVTFD : SInst<"vcvt_f64", "os", "Sl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Unsigned Integer Convert To Floating-point +def SCALAR_UCVTFS : SInst<"vcvt_f32", "ys", "SUi">; +def SCALAR_UCVTFD : SInst<"vcvt_f64", "os", "SUl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Converts +def SCALAR_FCVTXN : IInst<"vcvtx_f32", "ys", "Sd">; +def SCALAR_FCVTNSS : SInst<"vcvtn_s32", "$s", "Sf">; +def SCALAR_FCVTNUS : SInst<"vcvtn_u32", "bs", "Sf">; +def SCALAR_FCVTNSD : SInst<"vcvtn_s64", "$s", "Sd">; +def SCALAR_FCVTNUD : SInst<"vcvtn_u64", "bs", "Sd">; +def SCALAR_FCVTMSS : SInst<"vcvtm_s32", "$s", "Sf">; +def SCALAR_FCVTMUS : SInst<"vcvtm_u32", "bs", "Sf">; +def SCALAR_FCVTMSD : SInst<"vcvtm_s64", "$s", "Sd">; +def SCALAR_FCVTMUD : SInst<"vcvtm_u64", "bs", "Sd">; +def SCALAR_FCVTASS : SInst<"vcvta_s32", "$s", "Sf">; +def SCALAR_FCVTAUS : SInst<"vcvta_u32", "bs", "Sf">; +def SCALAR_FCVTASD : SInst<"vcvta_s64", "$s", "Sd">; +def SCALAR_FCVTAUD : SInst<"vcvta_u64", "bs", "Sd">; +def SCALAR_FCVTPSS : SInst<"vcvtp_s32", "$s", "Sf">; +def SCALAR_FCVTPUS : SInst<"vcvtp_u32", "bs", "Sf">; +def SCALAR_FCVTPSD : SInst<"vcvtp_s64", "$s", "Sd">; +def SCALAR_FCVTPUD : SInst<"vcvtp_u64", "bs", "Sd">; +def SCALAR_FCVTZSS : SInst<"vcvt_s32", "$s", "Sf">; +def SCALAR_FCVTZUS : SInst<"vcvt_u32", "bs", "Sf">; +def SCALAR_FCVTZSD : SInst<"vcvt_s64", "$s", "Sd">; +def SCALAR_FCVTZUD : SInst<"vcvt_u64", "bs", "Sd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Reciprocal Estimate +def SCALAR_FRECPE : IInst<"vrecpe", "ss", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Reciprocal Exponent +def SCALAR_FRECPX : IInst<"vrecpx", "ss", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Reciprocal Square Root Estimate +def SCALAR_FRSQRTE : IInst<"vrsqrte", "ss", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Integer Comparison +def SCALAR_CMEQ : SInst<"vceq", "sss", "SlSUl">; +def SCALAR_CMEQZ : SInst<"vceqz", "ss", "SlSUl">; +def SCALAR_CMGE : SInst<"vcge", "sss", "Sl">; +def SCALAR_CMGEZ : SInst<"vcgez", "ss", "Sl">; +def SCALAR_CMHS : SInst<"vcge", "sss", "SUl">; +def SCALAR_CMLE : SInst<"vcle", "sss", "SlSUl">; +def SCALAR_CMLEZ : SInst<"vclez", "ss", "Sl">; +def SCALAR_CMLT : SInst<"vclt", "sss", "SlSUl">; +def SCALAR_CMLTZ : SInst<"vcltz", "ss", "Sl">; +def SCALAR_CMGT : SInst<"vcgt", "sss", "Sl">; +def SCALAR_CMGTZ : SInst<"vcgtz", "ss", "Sl">; +def SCALAR_CMHI : SInst<"vcgt", "sss", "SUl">; +def SCALAR_CMTST : SInst<"vtst", "sss", "SlSUl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Comparison +def SCALAR_FCMEQ : IInst<"vceq", "bss", "SfSd">; +def SCALAR_FCMEQZ : IInst<"vceqz", "bs", "SfSd">; +def SCALAR_FCMGE : IInst<"vcge", "bss", "SfSd">; +def SCALAR_FCMGEZ : IInst<"vcgez", "bs", "SfSd">; +def SCALAR_FCMGT : IInst<"vcgt", "bss", "SfSd">; +def SCALAR_FCMGTZ : IInst<"vcgtz", "bs", "SfSd">; +def SCALAR_FCMLE : IInst<"vcle", "bss", "SfSd">; +def SCALAR_FCMLEZ : IInst<"vclez", "bs", "SfSd">; +def SCALAR_FCMLT : IInst<"vclt", "bss", "SfSd">; +def SCALAR_FCMLTZ : IInst<"vcltz", "bs", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Absolute Compare Mask Greater Than Or Equal +def SCALAR_FACGE : IInst<"vcage", "bss", "SfSd">; +def SCALAR_FACLE : IInst<"vcale", "bss", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Floating-point Absolute Compare Mask Greater Than +def SCALAR_FACGT : IInst<"vcagt", "bss", "SfSd">; +def SCALAR_FACLT : IInst<"vcalt", "bss", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Absolute Value +def SCALAR_ABS : SInst<"vabs", "ss", "Sl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Absolute Difference +def SCALAR_ABD : IInst<"vabd", "sss", "SfSd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Signed Saturating Absolute Value +def SCALAR_SQABS : SInst<"vqabs", "ss", "ScSsSiSl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Negate +def SCALAR_NEG : SInst<"vneg", "ss", "Sl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Signed Saturating Negate +def SCALAR_SQNEG : SInst<"vqneg", "ss", "ScSsSiSl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Signed Saturating Accumulated of Unsigned Value +def SCALAR_SUQADD : SInst<"vuqadd", "sss", "ScSsSiSl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Unsigned Saturating Accumulated of Signed Value +def SCALAR_USQADD : SInst<"vsqadd", "sss", "SUcSUsSUiSUl">; + +//////////////////////////////////////////////////////////////////////////////// +// Signed Saturating Doubling Multiply-Add Long +def SCALAR_SQDMLAL : SInst<"vqdmlal", "rrss", "SsSi">; + +//////////////////////////////////////////////////////////////////////////////// +// Signed Saturating Doubling Multiply-Subtract Long +def SCALAR_SQDMLSL : SInst<"vqdmlsl", "rrss", "SsSi">; + +//////////////////////////////////////////////////////////////////////////////// +// Signed Saturating Doubling Multiply Long +def SCALAR_SQDMULL : SInst<"vqdmull", "rss", "SsSi">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Signed Saturating Extract Unsigned Narrow +def SCALAR_SQXTUN : SInst<"vqmovun", "zs", "SsSiSl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Signed Saturating Extract Narrow +def SCALAR_SQXTN : SInst<"vqmovn", "zs", "SsSiSl">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar Unsigned Saturating Extract Narrow +def SCALAR_UQXTN : SInst<"vqmovn", "zs", "SUsSUiSUl">; + +// Scalar Floating Point multiply (scalar, by element) +def SCALAR_FMUL_LANE : IOpInst<"vmul_lane", "ssdi", "SfSd", OP_SCALAR_MUL_LN>; +def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "ssji", "SfSd", OP_SCALAR_MUL_LNQ>; + +// Scalar Floating Point multiply extended (scalar, by element) +def SCALAR_FMULX_LANE : IOpInst<"vmulx_lane", "ssdi", "SfSd", OP_SCALAR_MULX_LN>; +def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "ssji", "SfSd", OP_SCALAR_MULX_LNQ>; + +def SCALAR_VMUL_N : IInst<"vmul_n", "dds", "d">; + +// VMUL_LANE_A64 d type implemented using scalar mul lane +def SCALAR_VMUL_LANE : IInst<"vmul_lane", "ddgi", "d">; + +// VMUL_LANEQ d type implemented using scalar mul lane +def SCALAR_VMUL_LANEQ : IInst<"vmul_laneq", "ddji", "d">; + +// VMULX_LANE d type implemented using scalar vmulx_lane +def SCALAR_VMULX_LANE : IOpInst<"vmulx_lane", "ddgi", "d", OP_SCALAR_VMULX_LN>; + +// VMULX_LANEQ d type implemented using scalar vmulx_laneq +def SCALAR_VMULX_LANEQ : IOpInst<"vmulx_laneq", "ddji", "d", OP_SCALAR_VMULX_LNQ>; + +// Scalar Floating Point fused multiply-add (scalar, by element) +def SCALAR_FMLA_LANE : IInst<"vfma_lane", "sssdi", "SfSd">; +def SCALAR_FMLA_LANEQ : IInst<"vfma_laneq", "sssji", "SfSd">; + +// Scalar Floating Point fused multiply-subtract (scalar, by element) +def SCALAR_FMLS_LANE : IOpInst<"vfms_lane", "sssdi", "SfSd", OP_FMS_LN>; +def SCALAR_FMLS_LANEQ : IOpInst<"vfms_laneq", "sssji", "SfSd", OP_FMS_LNQ>; + +// Signed Saturating Doubling Multiply Long (scalar by element) +def SCALAR_SQDMULL_LANE : SOpInst<"vqdmull_lane", "rsdi", "SsSi", OP_SCALAR_QDMULL_LN>; +def SCALAR_SQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "rsji", "SsSi", OP_SCALAR_QDMULL_LNQ>; + +// Signed Saturating Doubling Multiply-Add Long (scalar by element) +def SCALAR_SQDMLAL_LANE : SInst<"vqdmlal_lane", "rrsdi", "SsSi">; +def SCALAR_SQDMLAL_LANEQ : SInst<"vqdmlal_laneq", "rrsji", "SsSi">; + +// Signed Saturating Doubling Multiply-Subtract Long (scalar by element) +def SCALAR_SQDMLS_LANE : SInst<"vqdmlsl_lane", "rrsdi", "SsSi">; +def SCALAR_SQDMLS_LANEQ : SInst<"vqdmlsl_laneq", "rrsji", "SsSi">; + +// Scalar Integer Saturating Doubling Multiply Half High (scalar by element) +def SCALAR_SQDMULH_LANE : SOpInst<"vqdmulh_lane", "ssdi", "SsSi", OP_SCALAR_QDMULH_LN>; +def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QDMULH_LNQ>; + +// Scalar Integer Saturating Rounding Doubling Multiply Half High +def SCALAR_SQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "ssdi", "SsSi", OP_SCALAR_QRDMULH_LN>; +def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QRDMULH_LNQ>; + +def SCALAR_VDUP_LANE : IInst<"vdup_lane", "sdi", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; +def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "sji", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; + +def SCALAR_GET_LANE : IOpInst<"vget_lane", "sdi", "hQh", OP_SCALAR_GET_LN>; +def SCALAR_SET_LANE : IOpInst<"vset_lane", "dsdi", "hQh", OP_SCALAR_SET_LN>; +} diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/CGFunctionInfo.h b/contrib/llvm/tools/clang/include/clang/CodeGen/CGFunctionInfo.h new file mode 100644 index 0000000..96da0e9 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/CGFunctionInfo.h @@ -0,0 +1,361 @@ +//==-- CGFunctionInfo.h - Representation of function argument/return types -==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Defines CGFunctionInfo and associated types used in representing the +// LLVM source types and ABI-coerced types for function arguments and +// return values. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGEN_FUNCTION_INFO_H +#define LLVM_CLANG_CODEGEN_FUNCTION_INFO_H + +#include "clang/AST/CanonicalType.h" +#include "clang/AST/Type.h" +#include "llvm/ADT/FoldingSet.h" + +#include <cassert> + +namespace llvm { + class Type; +} + +namespace clang { +namespace CodeGen { + +/// ABIArgInfo - Helper class to encapsulate information about how a +/// specific C type should be passed to or returned from a function. +class ABIArgInfo { +public: + enum Kind { + /// Direct - Pass the argument directly using the normal converted LLVM + /// type, or by coercing to another specified type stored in + /// 'CoerceToType'). If an offset is specified (in UIntData), then the + /// argument passed is offset by some number of bytes in the memory + /// representation. A dummy argument is emitted before the real argument + /// if the specified type stored in "PaddingType" is not zero. + Direct, + + /// Extend - Valid only for integer argument types. Same as 'direct' + /// but also emit a zero/sign extension attribute. + Extend, + + /// Indirect - Pass the argument indirectly via a hidden pointer + /// with the specified alignment (0 indicates default alignment). + Indirect, + + /// Ignore - Ignore the argument (treat as void). Useful for void and + /// empty structs. + Ignore, + + /// Expand - Only valid for aggregate argument types. The structure should + /// be expanded into consecutive arguments for its constituent fields. + /// Currently expand is only allowed on structures whose fields + /// are all scalar types or are themselves expandable types. + Expand, + + KindFirst=Direct, KindLast=Expand + }; + +private: + Kind TheKind; + llvm::Type *TypeData; + llvm::Type *PaddingType; + unsigned UIntData; + bool BoolData0; + bool BoolData1; + bool InReg; + bool PaddingInReg; + + ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR, + bool PIR, llvm::Type* P) + : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0), + BoolData1(B1), InReg(IR), PaddingInReg(PIR) {} + +public: + ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} + + static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0, + llvm::Type *Padding = 0) { + return ABIArgInfo(Direct, T, Offset, false, false, false, false, Padding); + } + static ABIArgInfo getDirectInReg(llvm::Type *T = 0) { + return ABIArgInfo(Direct, T, 0, false, false, true, false, 0); + } + static ABIArgInfo getExtend(llvm::Type *T = 0) { + return ABIArgInfo(Extend, T, 0, false, false, false, false, 0); + } + static ABIArgInfo getExtendInReg(llvm::Type *T = 0) { + return ABIArgInfo(Extend, T, 0, false, false, true, false, 0); + } + static ABIArgInfo getIgnore() { + return ABIArgInfo(Ignore, 0, 0, false, false, false, false, 0); + } + static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true + , bool Realign = false + , llvm::Type *Padding = 0) { + return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, false, + Padding); + } + static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true + , bool Realign = false) { + return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, false, 0); + } + static ABIArgInfo getExpand() { + return ABIArgInfo(Expand, 0, 0, false, false, false, false, 0); + } + static ABIArgInfo getExpandWithPadding(bool PaddingInReg, + llvm::Type *Padding) { + return ABIArgInfo(Expand, 0, 0, false, false, false, PaddingInReg, + Padding); + } + + Kind getKind() const { return TheKind; } + bool isDirect() const { return TheKind == Direct; } + bool isExtend() const { return TheKind == Extend; } + bool isIgnore() const { return TheKind == Ignore; } + bool isIndirect() const { return TheKind == Indirect; } + bool isExpand() const { return TheKind == Expand; } + + bool canHaveCoerceToType() const { + return TheKind == Direct || TheKind == Extend; + } + + // Direct/Extend accessors + unsigned getDirectOffset() const { + assert((isDirect() || isExtend()) && "Not a direct or extend kind"); + return UIntData; + } + + llvm::Type *getPaddingType() const { + return PaddingType; + } + + bool getPaddingInReg() const { + return PaddingInReg; + } + + llvm::Type *getCoerceToType() const { + assert(canHaveCoerceToType() && "Invalid kind!"); + return TypeData; + } + + void setCoerceToType(llvm::Type *T) { + assert(canHaveCoerceToType() && "Invalid kind!"); + TypeData = T; + } + + bool getInReg() const { + assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); + return InReg; + } + + // Indirect accessors + unsigned getIndirectAlign() const { + assert(TheKind == Indirect && "Invalid kind!"); + return UIntData; + } + + bool getIndirectByVal() const { + assert(TheKind == Indirect && "Invalid kind!"); + return BoolData0; + } + + bool getIndirectRealign() const { + assert(TheKind == Indirect && "Invalid kind!"); + return BoolData1; + } + + void dump() const; +}; + +/// A class for recording the number of arguments that a function +/// signature requires. +class RequiredArgs { + /// The number of required arguments, or ~0 if the signature does + /// not permit optional arguments. + unsigned NumRequired; +public: + enum All_t { All }; + + RequiredArgs(All_t _) : NumRequired(~0U) {} + explicit RequiredArgs(unsigned n) : NumRequired(n) { + assert(n != ~0U); + } + + /// Compute the arguments required by the given formal prototype, + /// given that there may be some additional, non-formal arguments + /// in play. + static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, + unsigned additional) { + if (!prototype->isVariadic()) return All; + return RequiredArgs(prototype->getNumArgs() + additional); + } + + static RequiredArgs forPrototype(const FunctionProtoType *prototype) { + return forPrototypePlus(prototype, 0); + } + + static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { + return forPrototype(prototype.getTypePtr()); + } + + static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, + unsigned additional) { + return forPrototypePlus(prototype.getTypePtr(), additional); + } + + bool allowsOptionalArgs() const { return NumRequired != ~0U; } + unsigned getNumRequiredArgs() const { + assert(allowsOptionalArgs()); + return NumRequired; + } + + unsigned getOpaqueData() const { return NumRequired; } + static RequiredArgs getFromOpaqueData(unsigned value) { + if (value == ~0U) return All; + return RequiredArgs(value); + } +}; + +/// CGFunctionInfo - Class to encapsulate the information about a +/// function definition. +class CGFunctionInfo : public llvm::FoldingSetNode { + struct ArgInfo { + CanQualType type; + ABIArgInfo info; + }; + + /// The LLVM::CallingConv to use for this function (as specified by the + /// user). + unsigned CallingConvention : 8; + + /// The LLVM::CallingConv to actually use for this function, which may + /// depend on the ABI. + unsigned EffectiveCallingConvention : 8; + + /// The clang::CallingConv that this was originally created with. + unsigned ASTCallingConvention : 8; + + /// Whether this function is noreturn. + unsigned NoReturn : 1; + + /// Whether this function is returns-retained. + unsigned ReturnsRetained : 1; + + /// How many arguments to pass inreg. + unsigned HasRegParm : 1; + unsigned RegParm : 4; + + RequiredArgs Required; + + unsigned NumArgs; + ArgInfo *getArgsBuffer() { + return reinterpret_cast<ArgInfo*>(this+1); + } + const ArgInfo *getArgsBuffer() const { + return reinterpret_cast<const ArgInfo*>(this + 1); + } + + CGFunctionInfo() : Required(RequiredArgs::All) {} + +public: + static CGFunctionInfo *create(unsigned llvmCC, + const FunctionType::ExtInfo &extInfo, + CanQualType resultType, + ArrayRef<CanQualType> argTypes, + RequiredArgs required); + + typedef const ArgInfo *const_arg_iterator; + typedef ArgInfo *arg_iterator; + + const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } + const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; } + arg_iterator arg_begin() { return getArgsBuffer() + 1; } + arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; } + + unsigned arg_size() const { return NumArgs; } + + bool isVariadic() const { return Required.allowsOptionalArgs(); } + RequiredArgs getRequiredArgs() const { return Required; } + + bool isNoReturn() const { return NoReturn; } + + /// In ARC, whether this function retains its return value. This + /// is not always reliable for call sites. + bool isReturnsRetained() const { return ReturnsRetained; } + + /// getASTCallingConvention() - Return the AST-specified calling + /// convention. + CallingConv getASTCallingConvention() const { + return CallingConv(ASTCallingConvention); + } + + /// getCallingConvention - Return the user specified calling + /// convention, which has been translated into an LLVM CC. + unsigned getCallingConvention() const { return CallingConvention; } + + /// getEffectiveCallingConvention - Return the actual calling convention to + /// use, which may depend on the ABI. + unsigned getEffectiveCallingConvention() const { + return EffectiveCallingConvention; + } + void setEffectiveCallingConvention(unsigned Value) { + EffectiveCallingConvention = Value; + } + + bool getHasRegParm() const { return HasRegParm; } + unsigned getRegParm() const { return RegParm; } + + FunctionType::ExtInfo getExtInfo() const { + return FunctionType::ExtInfo(isNoReturn(), + getHasRegParm(), getRegParm(), + getASTCallingConvention(), + isReturnsRetained()); + } + + CanQualType getReturnType() const { return getArgsBuffer()[0].type; } + + ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; } + const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } + + void Profile(llvm::FoldingSetNodeID &ID) { + ID.AddInteger(getASTCallingConvention()); + ID.AddBoolean(NoReturn); + ID.AddBoolean(ReturnsRetained); + ID.AddBoolean(HasRegParm); + ID.AddInteger(RegParm); + ID.AddInteger(Required.getOpaqueData()); + getReturnType().Profile(ID); + for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it) + it->type.Profile(ID); + } + static void Profile(llvm::FoldingSetNodeID &ID, + const FunctionType::ExtInfo &info, + RequiredArgs required, + CanQualType resultType, + ArrayRef<CanQualType> argTypes) { + ID.AddInteger(info.getCC()); + ID.AddBoolean(info.getNoReturn()); + ID.AddBoolean(info.getProducesResult()); + ID.AddBoolean(info.getHasRegParm()); + ID.AddInteger(info.getRegParm()); + ID.AddInteger(required.getOpaqueData()); + resultType.Profile(ID); + for (ArrayRef<CanQualType>::iterator + i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { + i->Profile(ID); + } + } +}; + +} // end namespace CodeGen +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenABITypes.h b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenABITypes.h new file mode 100644 index 0000000..81e2cdc --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -0,0 +1,80 @@ +//==---- CodeGenABITypes.h - Convert Clang types to LLVM types for ABI -----==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// CodeGenABITypes is a simple interface for getting LLVM types for +// the parameters and the return value of a function given the Clang +// types. +// +// The class is implemented as a public wrapper around the private +// CodeGenTypes class in lib/CodeGen. +// +// It allows other clients, like LLDB, to determine the LLVM types that are +// actually used in function calls, which makes it possible to then determine +// the acutal ABI locations (e.g. registers, stack locations, etc.) that +// these parameters are stored in. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGEN_ABITYPES_H +#define LLVM_CLANG_CODEGEN_ABITYPES_H + +#include "clang/AST/CanonicalType.h" +#include "clang/AST/Type.h" +#include "clang/CodeGen/CGFunctionInfo.h" + +namespace llvm { + class DataLayout; + class Module; +} + +namespace clang { +class ASTContext; +class CXXRecordDecl; +class CodeGenOptions; +class DiagnosticsEngine; +class ObjCMethodDecl; + +namespace CodeGen { +class CGFunctionInfo; +class CodeGenModule; + +class CodeGenABITypes +{ +public: + CodeGenABITypes(ASTContext &C, const CodeGenOptions &CodeGenOpts, + llvm::Module &M, const llvm::DataLayout &TD, + DiagnosticsEngine &Diags); + + ~CodeGenABITypes(); + + /// These methods all forward to methods in the private implementation class + /// CodeGenTypes. + + const CGFunctionInfo &arrangeObjCMessageSendSignature( + const ObjCMethodDecl *MD, + QualType receiverType); + const CGFunctionInfo &arrangeFreeFunctionType( + CanQual<FunctionProtoType> Ty); + const CGFunctionInfo &arrangeFreeFunctionType( + CanQual<FunctionNoProtoType> Ty); + const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD, + const FunctionProtoType *FTP); + const CGFunctionInfo &arrangeLLVMFunctionInfo(CanQualType returnType, + llvm::ArrayRef<CanQualType> argTypes, + FunctionType::ExtInfo info, + RequiredArgs args); + +private: + CodeGen::CodeGenModule *CGM; +}; + +} // end namespace CodeGen +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Action.h b/contrib/llvm/tools/clang/include/clang/Driver/Action.h index 4057e48..289dbe3 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Action.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Action.h @@ -14,9 +14,14 @@ #include "clang/Driver/Util.h" #include "llvm/ADT/SmallVector.h" +namespace llvm { +namespace opt { + class Arg; +} +} + namespace clang { namespace driver { - class Arg; /// Action - Represent an abstract compilation step to perform. /// @@ -94,11 +99,12 @@ public: class InputAction : public Action { virtual void anchor(); - const Arg &Input; + const llvm::opt::Arg &Input; + public: - InputAction(const Arg &_Input, types::ID _Type); + InputAction(const llvm::opt::Arg &_Input, types::ID _Type); - const Arg &getInputArg() const { return Input; } + const llvm::opt::Arg &getInputArg() const { return Input; } static bool classof(const Action *A) { return A->getKind() == InputClass; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Arg.h b/contrib/llvm/tools/clang/include/clang/Driver/Arg.h deleted file mode 100644 index 662a2e2..0000000 --- a/contrib/llvm/tools/clang/include/clang/Driver/Arg.h +++ /dev/null @@ -1,133 +0,0 @@ -//===--- Arg.h - Parsed Argument Classes ------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines the clang::driver::Arg class for parsed arguments. -/// -//===----------------------------------------------------------------------===// - -#ifndef CLANG_DRIVER_ARG_H_ -#define CLANG_DRIVER_ARG_H_ - -#include "Util.h" -#include "clang/Driver/Option.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include <string> - -namespace clang { -namespace driver { - class ArgList; - - /// \brief A concrete instance of a particular driver option. - /// - /// The Arg class encodes just enough information to be able to - /// derive the argument values efficiently. In addition, Arg - /// instances have an intrusive double linked list which is used by - /// ArgList to provide efficient iteration over all instances of a - /// particular option. - class Arg { - 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; - - /// \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; - - /// \brief Was this argument used to affect compilation? - /// - /// This is used for generating "argument unused" diagnostics. - mutable unsigned Claimed : 1; - - /// \brief Does this argument own its values? - mutable unsigned OwnsValues : 1; - - /// \brief The argument values, as C strings. - SmallVector<const char *, 2> Values; - - public: - 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, StringRef Spelling, unsigned Index, - const char *Value0, const char *Value1, const Arg *BaseArg = 0); - ~Arg(); - - Option getOption() const { return Opt; } - StringRef getSpelling() const { return Spelling; } - unsigned getIndex() const { return Index; } - - /// \brief Return the base argument which generated this arg. - /// - /// This is either the argument itself or the argument it was - /// derived from during tool chain specific argument translation. - const Arg &getBaseArg() const { - return BaseArg ? *BaseArg : *this; - } - void setBaseArg(const Arg *_BaseArg) { - BaseArg = _BaseArg; - } - - bool getOwnsValues() const { return OwnsValues; } - void setOwnsValues(bool Value) const { OwnsValues = Value; } - - bool isClaimed() const { return getBaseArg().Claimed; } - - /// \brief Set the Arg claimed bit. - void claim() const { getBaseArg().Claimed = true; } - - unsigned getNumValues() const { return Values.size(); } - const char *getValue(unsigned N = 0) const { - return Values[N]; - } - - SmallVectorImpl<const char*> &getValues() { - return Values; - } - - bool containsValue(StringRef Value) const { - for (unsigned i = 0, e = getNumValues(); i != e; ++i) - if (Values[i] == Value) - return true; - return false; - } - - /// \brief Append the argument onto the given array as strings. - void render(const ArgList &Args, ArgStringList &Output) const; - - /// \brief Append the argument, render as an input, onto the given - /// array as strings. - /// - /// The distinction is that some options only render their values - /// when rendered as a input (e.g., Xlinker). - void renderAsInput(const ArgList &Args, ArgStringList &Output) const; - - void dump() const; - - /// \brief Return a formatted version of the argument and - /// its values, for debugging and diagnostics. - std::string getAsString(const ArgList &Args) const; - }; - -} // end namespace driver -} // end namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h b/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h deleted file mode 100644 index 9db170c..0000000 --- a/contrib/llvm/tools/clang/include/clang/Driver/ArgList.h +++ /dev/null @@ -1,442 +0,0 @@ -//===--- ArgList.h - Argument List Management ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CLANG_DRIVER_ARGLIST_H_ -#define CLANG_DRIVER_ARGLIST_H_ - -#include "clang/Basic/LLVM.h" -#include "clang/Driver/OptSpecifier.h" -#include "clang/Driver/Option.h" -#include "clang/Driver/Util.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include <list> -#include <string> -#include <vector> - -namespace clang { - class DiagnosticsEngine; - -namespace driver { - class Arg; - class ArgList; - class Option; - - /// arg_iterator - Iterates through arguments stored inside an ArgList. - class arg_iterator { - /// The current argument. - SmallVectorImpl<Arg*>::const_iterator Current; - - /// The argument list we are iterating over. - const ArgList &Args; - - /// Optional filters on the arguments which will be match. Most clients - /// should never want to iterate over arguments without filters, so we won't - /// bother to factor this into two separate iterator implementations. - // - // FIXME: Make efficient; the idea is to provide efficient iteration over - // all arguments which match a particular id and then just provide an - // iterator combinator which takes multiple iterators which can be - // efficiently compared and returns them in order. - OptSpecifier Id0, Id1, Id2; - - void SkipToNextArg(); - - public: - typedef Arg * const * value_type; - typedef Arg * const & reference; - typedef Arg * const * pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; - - arg_iterator(SmallVectorImpl<Arg*>::const_iterator it, - const ArgList &_Args, OptSpecifier _Id0 = 0U, - OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U) - : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) { - SkipToNextArg(); - } - - operator const Arg*() { return *Current; } - reference operator*() const { return *Current; } - pointer operator->() const { return Current; } - - arg_iterator &operator++() { - ++Current; - SkipToNextArg(); - return *this; - } - - arg_iterator operator++(int) { - arg_iterator tmp(*this); - ++(*this); - return tmp; - } - - friend bool operator==(arg_iterator LHS, arg_iterator RHS) { - return LHS.Current == RHS.Current; - } - friend bool operator!=(arg_iterator LHS, arg_iterator RHS) { - return !(LHS == RHS); - } - }; - - /// ArgList - Ordered collection of driver arguments. - /// - /// The ArgList class manages a list of Arg instances as well as - /// auxiliary data and convenience methods to allow Tools to quickly - /// check for the presence of Arg instances for a particular Option - /// and to iterate over groups of arguments. - class ArgList { - private: - ArgList(const ArgList &) LLVM_DELETED_FUNCTION; - void operator=(const ArgList &) LLVM_DELETED_FUNCTION; - - public: - typedef SmallVector<Arg*, 16> arglist_type; - typedef arglist_type::iterator iterator; - typedef arglist_type::const_iterator const_iterator; - typedef arglist_type::reverse_iterator reverse_iterator; - typedef arglist_type::const_reverse_iterator const_reverse_iterator; - - private: - /// The internal list of arguments. - arglist_type Args; - - protected: - ArgList(); - - public: - virtual ~ArgList(); - - /// @name Arg Access - /// @{ - - /// append - Append \p A to the arg list. - void append(Arg *A); - - arglist_type &getArgs() { return Args; } - const arglist_type &getArgs() const { return Args; } - - unsigned size() const { return Args.size(); } - - /// @} - /// @name Arg Iteration - /// @{ - - iterator begin() { return Args.begin(); } - iterator end() { return Args.end(); } - - reverse_iterator rbegin() { return Args.rbegin(); } - reverse_iterator rend() { return Args.rend(); } - - const_iterator begin() const { return Args.begin(); } - const_iterator end() const { return Args.end(); } - - const_reverse_iterator rbegin() const { return Args.rbegin(); } - const_reverse_iterator rend() const { return Args.rend(); } - - arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U, - OptSpecifier Id2 = 0U) const { - return arg_iterator(Args.begin(), *this, Id0, Id1, Id2); - } - arg_iterator filtered_end() const { - return arg_iterator(Args.end(), *this); - } - - /// @} - /// @name Arg Removal - /// @{ - - /// eraseArg - Remove any option matching \p Id. - void eraseArg(OptSpecifier Id); - - /// @} - /// @name Arg Access - /// @{ - - /// hasArg - Does the arg list contain any option matching \p Id. - /// - /// \p Claim Whether the argument should be claimed, if it exists. - bool hasArgNoClaim(OptSpecifier Id) const { - return getLastArgNoClaim(Id) != 0; - } - bool hasArg(OptSpecifier Id) const { - return getLastArg(Id) != 0; - } - bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const { - return getLastArg(Id0, Id1) != 0; - } - bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const { - return getLastArg(Id0, Id1, Id2) != 0; - } - - /// getLastArg - Return the last argument matching \p Id, or null. - /// - /// \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; - Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const; - Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, - OptSpecifier Id3) const; - Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, - OptSpecifier Id3, OptSpecifier Id4) const; - Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, - OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5) const; - Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, - OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5, - OptSpecifier Id6) const; - Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, - OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5, - OptSpecifier Id6, OptSpecifier Id7) const; - - /// 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, - /// which are guaranteed to be the first strings in the argument string - /// list. - virtual unsigned getNumInputArgStrings() const = 0; - - /// @} - /// @name Argument Lookup Utilities - /// @{ - - /// getLastArgValue - Return the value of the last argument, or a default. - StringRef getLastArgValue(OptSpecifier Id, - StringRef Default = "") const; - - /// getLastArgValue - Return the value of the last argument as an integer, - /// or a default. If Diags is non-null, emits an error if the argument - /// is given, but non-integral. - int getLastArgIntValue(OptSpecifier Id, int Default, - DiagnosticsEngine *Diags = 0) const; - - /// getLastArgValue - Return the value of the last argument as an integer, - /// or a default. Emits an error if the argument is given, but non-integral. - int getLastArgIntValue(OptSpecifier Id, int Default, - DiagnosticsEngine &Diags) const { - return getLastArgIntValue(Id, Default, &Diags); - } - - /// getAllArgValues - Get the values of all instances of the given argument - /// as strings. - std::vector<std::string> getAllArgValues(OptSpecifier Id) const; - - /// @} - /// @name Translation Utilities - /// @{ - - /// 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; - - /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative - /// form \p Neg, return true if the option or its alias is present, false if - /// the negation is present, and \p Default if none of the options are - /// given. If multiple options are present, the last one wins. - bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg, - bool Default = true) const; - - /// AddLastArg - Render only the last argument match \p Id0, if present. - void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; - void AddLastArg(ArgStringList &Output, OptSpecifier Id0, - OptSpecifier Id1) const; - - /// AddAllArgs - Render all arguments matching the given ids. - void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, - OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; - - /// AddAllArgValues - Render the argument values of all arguments - /// matching the given ids. - void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, - OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; - - /// AddAllArgsTranslated - Render all the arguments matching the - /// given ids, but forced to separate args and using the provided - /// name instead of the first option value. - /// - /// \param Joined - If true, render the argument as joined with - /// the option specifier. - void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, - const char *Translation, - bool Joined = false) const; - - /// ClaimAllArgs - Claim all arguments which match the given - /// option id. - void ClaimAllArgs(OptSpecifier Id0) const; - - /// ClaimAllArgs - Claim all arguments. - /// - void ClaimAllArgs() const; - - /// @} - /// @name Arg Synthesis - /// @{ - - /// MakeArgString - Construct a constant string pointer whose - /// lifetime will match that of the ArgList. - virtual const char *MakeArgString(StringRef Str) const = 0; - const char *MakeArgString(const char *Str) const { - return MakeArgString(StringRef(Str)); - } - const char *MakeArgString(std::string Str) const { - return MakeArgString(StringRef(Str)); - } - const char *MakeArgString(const Twine &Str) const; - - /// \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; - - /// @} - - void dump(); - }; - - class InputArgList : public ArgList { - private: - /// List of argument strings used by the contained Args. - /// - /// This is mutable since we treat the ArgList as being the list - /// of Args, and allow routines to add new strings (to have a - /// convenient place to store the memory) via MakeIndex. - mutable ArgStringList ArgStrings; - - /// Strings for synthesized arguments. - /// - /// This is mutable since we treat the ArgList as being the list - /// of Args, and allow routines to add new strings (to have a - /// convenient place to store the memory) via MakeIndex. - mutable std::list<std::string> SynthesizedStrings; - - /// The number of original input argument strings. - unsigned NumInputArgStrings; - - public: - InputArgList(const char* const *ArgBegin, const char* const *ArgEnd); - ~InputArgList(); - - virtual const char *getArgString(unsigned Index) const { - return ArgStrings[Index]; - } - - virtual unsigned getNumInputArgStrings() const { - return NumInputArgStrings; - } - - /// @name Arg Synthesis - /// @{ - - public: - /// MakeIndex - Get an index for the given string(s). - unsigned MakeIndex(StringRef String0) const; - unsigned MakeIndex(StringRef String0, StringRef String1) const; - - virtual const char *MakeArgString(StringRef Str) const; - - /// @} - }; - - /// DerivedArgList - An ordered collection of driver arguments, - /// whose storage may be in another argument list. - class DerivedArgList : public ArgList { - const InputArgList &BaseArgs; - - /// The list of arguments we synthesized. - mutable arglist_type SynthesizedArgs; - - public: - /// Construct a new derived arg list from \p BaseArgs. - DerivedArgList(const InputArgList &BaseArgs); - ~DerivedArgList(); - - virtual const char *getArgString(unsigned Index) const { - return BaseArgs.getArgString(Index); - } - - virtual unsigned getNumInputArgStrings() const { - return BaseArgs.getNumInputArgStrings(); - } - - const InputArgList &getBaseArgs() const { - return BaseArgs; - } - - /// @name Arg Synthesis - /// @{ - - /// AddSynthesizedArg - Add a argument to the list of synthesized arguments - /// (to be freed). - void AddSynthesizedArg(Arg *A) { - SynthesizedArgs.push_back(A); - } - - virtual const char *MakeArgString(StringRef Str) const; - - /// 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) { - append(MakeFlagArg(BaseArg, Opt)); - } - - /// AddPositionalArg - Construct a new Positional arg for the given option - /// \p Id, with the provided \p Value and append it to the argument - /// list. - 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 - /// \p Id, with the provided \p Value and append it to the argument - /// list. - 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 - /// \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 \p Id. - Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const; - - /// MakePositionalArg - Construct a new Positional arg for the - /// 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 \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 \p Id, with the provided \p Value. - Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt, - StringRef Value) const; - - /// @} - }; - -} // end namespace driver -} // end namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h index 420a101..345f50a 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.h @@ -10,24 +10,27 @@ #ifndef CLANG_DRIVER_CC1ASOPTIONS_H #define CLANG_DRIVER_CC1ASOPTIONS_H +namespace llvm { +namespace opt { + class OptTable; +} +} + namespace clang { namespace driver { - class OptTable; namespace cc1asoptions { enum ID { OPT_INVALID = 0, // This is not an option ID. -#define PREFIX(NAME, VALUE) -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR) OPT_##ID, #include "clang/Driver/CC1AsOptions.inc" LastOption #undef OPTION -#undef PREFIX }; } - OptTable *createCC1AsOptTable(); +llvm::opt::OptTable *createCC1AsOptTable(); } } diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td index 2749bcd..b536724 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1AsOptions.td @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// // Include the common option parsing interfaces. -include "OptParser.td" +include "llvm/Option/OptParser.td" //===----------------------------------------------------------------------===// // Target Options @@ -33,7 +33,7 @@ def I : JoinedOrSeparate<["-"], "I">, MetaVarName<"<directory>">, HelpText<"Add directory to include search path">; def n : Flag<["-"], "n">, HelpText<"Don't automatically start assembly file with a text section">; -def L : Flag<["-"], "L">, +def msave_temp_labels : Flag<["-"], "msave-temp-labels">, HelpText<"Save temporary labels in the symbol table. " "Note this may change .s semantics, it should almost never be used " "on compiler generated code!">; @@ -77,15 +77,12 @@ def show_inst : Flag<["-"], "show-inst">, // Assemble Options //===----------------------------------------------------------------------===// -def relax_all : Flag<["-"], "relax-all">, +def mrelax_all : Flag<["-"], "mrelax-all">, HelpText<"Relax all fixups (for performance testing)">; -def no_exec_stack : Flag<["--"], "noexecstack">, +def mno_exec_stack : Flag<["-"], "mnoexecstack">, HelpText<"Mark the file as not needing an executable stack">; -def fatal_warnings : Flag<["--"], "fatal-warnings">, - HelpText<"Consider warnings as errors">; - def g : Flag<["-"], "g">, HelpText<"Generate source level debug information">; def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">, diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td index 96a50fc..85cfdcf 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td @@ -23,6 +23,8 @@ def target_abi : Separate<["-"], "target-abi">, HelpText<"Target a particular ABI type">; def target_cpu : Separate<["-"], "target-cpu">, HelpText<"Target a specific cpu type">; +def mfpmath : Separate<["-"], "mfpmath">, + HelpText<"Which unit to use for fp math">; def target_feature : Separate<["-"], "target-feature">, HelpText<"Target specific attributes">; def target_linker_version : Separate<["-"], "target-linker-version">, @@ -136,6 +138,8 @@ def dwarf_column_info : Flag<["-"], "dwarf-column-info">, HelpText<"Turn on column location information.">; def split_dwarf : Flag<["-"], "split-dwarf">, HelpText<"Split out the dwarf .dwo sections">; +def gnu_pubnames : Flag<["-"], "gnu-pubnames">, + HelpText<"Emit newer GNU style pubnames">; 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">, @@ -161,8 +165,8 @@ def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfie HelpText<"Use register sized accesses to bit-fields, when possible.">; def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, HelpText<"Turn off Type Based Alias Analysis">; -def struct_path_tbaa : Flag<["-"], "struct-path-tbaa">, - HelpText<"Turn on struct-path aware Type Based Alias Analysis">; +def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">, + HelpText<"Turn off struct-path aware Type Based Alias Analysis">; def masm_verbose : Flag<["-"], "masm-verbose">, HelpText<"Generate verbose assembly output">; def mcode_model : Separate<["-"], "mcode-model">, @@ -204,6 +208,14 @@ def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">, HelpText<"Emit complete constructors and destructors as aliases when possible">; def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">, HelpText<"Link the given bitcode file before performing optimizations.">; +def vectorize_loops : Flag<["-"], "vectorize-loops">, + HelpText<"Run the Loop vectorization passes">; +def vectorize_slp : Flag<["-"], "vectorize-slp">, + HelpText<"Run the SLP vectorization passes">; +def vectorize_slp_aggressive : Flag<["-"], "vectorize-slp-aggressive">, + HelpText<"Run the BB vectorization passes">; +def dependent_lib : Joined<["--"], "dependent-lib=">, + HelpText<"Add dependent library">; //===----------------------------------------------------------------------===// // Dependency Output Options @@ -213,6 +225,8 @@ def sys_header_deps : Flag<["-"], "sys-header-deps">, HelpText<"Include system headers in dependency output">; def header_include_file : Separate<["-"], "header-include-file">, HelpText<"Filename (or -) to write header include output to">; +def show_includes : Flag<["--"], "show-includes">, + HelpText<"Print cl.exe style /showIncludes to stderr">; //===----------------------------------------------------------------------===// // Diagnostic Options @@ -290,6 +304,8 @@ def ast_dump_filter : Separate<["-"], "ast-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" " -ast-list to list all filterable declaration node names.">; +def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">, + HelpText<"Include name lookup table dumps in AST dumps">; def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">, HelpText<"Do not automatically generate or update the global module index">; @@ -320,8 +336,6 @@ def ast_list : Flag<["-"], "ast-list">, HelpText<"Build ASTs and print the list of declaration node qualified names">; def ast_dump : Flag<["-"], "ast-dump">, HelpText<"Build ASTs and then debug dump them">; -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">, HelpText<"Build ASTs and view them with GraphViz">; def print_decl_contexts : Flag<["-"], "print-decl-contexts">, @@ -357,8 +371,6 @@ def arcmt_modify : Flag<["-"], "arcmt-modify">, def arcmt_migrate : Flag<["-"], "arcmt-migrate">, HelpText<"Apply modifications and produces temporary files that conform to ARC">; -def relocatable_pch : Flag<["-", "--"], "relocatable-pch">, - HelpText<"Whether to build a relocatable precompiled header">; def print_stats : Flag<["-"], "print-stats">, HelpText<"Print performance metrics and statistics">; def fdump_record_layouts : Flag<["-"], "fdump-record-layouts">, @@ -391,8 +403,6 @@ def main_file_name : Separate<["-"], "main-file-name">, HelpText<"Main file name to use for debug info">; def split_dwarf_file : Separate<["-"], "split-dwarf-file">, HelpText<"File name to use for split dwarf debug info output">; -def fno_signed_char : Flag<["-"], "fno-signed-char">, - HelpText<"Char is unsigned">; def fno_wchar : Flag<["-"], "fno-wchar">, HelpText<"Disable C++ builtin type wchar_t">; def fconstant_string_class : Separate<["-"], "fconstant-string-class">, @@ -404,8 +414,8 @@ 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=">, HelpText<"Objective-C dispatch method to use">; -def fobjc_default_synthesize_properties : Flag<["-"], "fobjc-default-synthesize-properties">, - HelpText<"enable the default synthesis of Objective-C properties">; +def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-default-synthesize-properties">, + HelpText<"disable the default synthesis of Objective-C properties">; def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">, HelpText<"enable extended encoding of block type signature">; def pic_level : Separate<["-"], "pic-level">, @@ -432,8 +442,12 @@ def ftype_visibility : Separate<["-"], "ftype-visibility">, HelpText<"Default type visibility">; def ftemplate_depth : Separate<["-"], "ftemplate-depth">, HelpText<"Maximum depth of recursive template instantiation">; +def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">, + HelpText<"Maximum number of 'operator->'s to call for a member access">; def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">, HelpText<"Maximum depth of recursive constexpr function calls">; +def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">, + HelpText<"Maximum number of steps in constexpr function evaluation">; def fbracket_depth : Separate<["-"], "fbracket-depth">, HelpText<"Maximum nesting level for parentheses, brackets, and braces">; def fconst_strings : Flag<["-"], "fconst-strings">, @@ -444,6 +458,8 @@ 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">, HelpText<"Use a fake address space map; OpenCL testing purposes only">; +def faddress_space_map_mangling_EQ : Joined<["-"], "faddress-space-map-mangling=">, MetaVarName<"<yes|no|target>">, + HelpText<"Set the mode for address space map based mangling; OpenCL testing purposes only">; 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">, @@ -456,6 +472,10 @@ def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">, HelpText<"Defines the __DEPRECATED macro">; def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">, HelpText<"Undefines the __DEPRECATED macro">; +def fsized_deallocation : Flag<["-"], "fsized-deallocation">, + HelpText<"Enable C++1y sized global deallocation functions">; +def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">, + HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">; //===----------------------------------------------------------------------===// // Header Search Options @@ -463,9 +483,6 @@ def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">, def nostdsysteminc : Flag<["-"], "nostdsysteminc">, HelpText<"Disable standard system #include directories">; -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">, HelpText<"Disable the module hash">; def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">, diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td b/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td new file mode 100644 index 0000000..d17a63c --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td @@ -0,0 +1,255 @@ +//===--- CLCompatOptions.td - Options for clang-cl ------------------------===// +// +// 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 accepted by clang-cl. +// +//===----------------------------------------------------------------------===// + +def cl_Group : OptionGroup<"<clang-cl options>">, + HelpText<"CL.EXE COMPATIBILITY OPTIONS">; + +def cl_compile_Group : OptionGroup<"<clang-cl compile-only options>">, + Group<cl_Group>; + +def cl_ignored_Group : OptionGroup<"<clang-cl ignored options>">, + Group<cl_Group>; + +class CLFlag<string name> : Option<["/", "-"], name, KIND_FLAG>, + Group<cl_Group>, Flags<[CLOption, DriverOption]>; + +class CLCompileFlag<string name> : Option<["/", "-"], name, KIND_FLAG>, + Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>; + +class CLIgnoredFlag<string name> : Option<["/", "-"], name, KIND_FLAG>, + Group<cl_ignored_Group>, Flags<[CLOption, DriverOption, HelpHidden]>; + +class CLJoined<string name> : Option<["/", "-"], name, KIND_JOINED>, + Group<cl_Group>, Flags<[CLOption, DriverOption]>; + +class CLCompileJoined<string name> : Option<["/", "-"], name, KIND_JOINED>, + Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>; + +class CLIgnoredJoined<string name> : Option<["/", "-"], name, KIND_JOINED>, + Group<cl_ignored_Group>, Flags<[CLOption, DriverOption, HelpHidden]>; + +class CLJoinedOrSeparate<string name> : Option<["/", "-"], name, + KIND_JOINED_OR_SEPARATE>, Group<cl_Group>, Flags<[CLOption, DriverOption]>; + +class CLCompileJoinedOrSeparate<string name> : Option<["/", "-"], name, + KIND_JOINED_OR_SEPARATE>, Group<cl_compile_Group>, + Flags<[CLOption, DriverOption]>; + +class CLRemainingArgs<string name> : Option<["/", "-"], name, + KIND_REMAINING_ARGS>, Group<cl_Group>, Flags<[CLOption, DriverOption]>; + +// Aliases: +// (We don't put any of these in cl_compile_Group as the options they alias are +// already in the right group.) + +def _SLASH_C : CLFlag<"C">, HelpText<"Don't discard comments when preprocessing">, + Alias<C>; +def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>; +def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">, + MetaVarName<"<macro[=value]>">, Alias<D>; +def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable RTTI">, Alias<frtti>; +def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable RTTI">, Alias<fno_rtti>; +def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, + Alias<fwritable_strings>; +def _SLASH_help : CLFlag<"help">, Alias<help>, + HelpText<"Display available options">; +def _SLASH_HELP : CLFlag<"HELP">, Alias<help>; +def _SLASH_I : CLJoinedOrSeparate<"I">, + HelpText<"Add directory to include search path">, MetaVarName<"<dir>">, + Alias<I>; +def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">, + Alias<funsigned_char>; +def _SLASH_O : CLJoined<"O">, HelpText<"Optimization level">, + MetaVarName<"<n>">, Alias<O>; +def _SLASH_Ob0 : CLFlag<"Ob0">, HelpText<"Disable inlining">, + Alias<fno_inline>; +def _SLASH_Od : CLFlag<"Od">, HelpText<"Disable optimization">, Alias<O0>; +def _SLASH_Oi : CLFlag<"Oi">, HelpText<"Enable use of builtin functions">, + Alias<fbuiltin>; +def _SLASH_Oi_ : CLFlag<"Oi-">, HelpText<"Disable use of builtin functions">, + Alias<fno_builtin>; +def _SLASH_Os : CLFlag<"Os">, HelpText<"Optimize for size">, Alias<O>, + AliasArgs<["s"]>; +def _SLASH_Ot : CLFlag<"Ot">, HelpText<"Optimize for speed">, Alias<O>, + AliasArgs<["2"]>; +def _SLASH_Ox : CLFlag<"Ox">, HelpText<"Maximum optimization">, Alias<O>, + AliasArgs<["3"]>; +def _SLASH_Oy : CLFlag<"Oy">, HelpText<"Enable frame pointer omission">, + Alias<fomit_frame_pointer>; +def _SLASH_Oy_ : CLFlag<"Oy-">, HelpText<"Disable frame pointer omission">, + Alias<fno_omit_frame_pointer>; +def _SLASH_P : CLFlag<"P">, HelpText<"Only run the preprocessor">, Alias<E>; +def _SLASH_QUESTION : CLFlag<"?">, Alias<help>, + HelpText<"Display available options">; +def _SLASH_showIncludes : CLFlag<"showIncludes">, + HelpText<"Print info about included files to stderr">, + Alias<show_includes>; +def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">, + MetaVarName<"<macro>">, Alias<U>; +def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>; +def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias<Wall>; +def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias<Wall>; +def _SLASH_W3 : CLFlag<"W3">, HelpText<"Enable -Wall">, Alias<Wall>; +def _SLASH_W4 : CLFlag<"W4">, HelpText<"Enable -Wall">, Alias<Wall>; +def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Wall">, Alias<Wall>; +def _SLASH_WX : CLFlag<"WX">, HelpText<"Treat warnings as errors">, + Alias<W_Joined>, AliasArgs<["error"]>; +def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">, + Alias<W_Joined>, AliasArgs<["no-error"]>; +def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>; +def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">, + Alias<fsyntax_only>; + + +// Non-aliases: + +def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>; + +def _SLASH_FA : CLFlag<"FA">, + HelpText<"Output assembly code file during compilation">; +def _SLASH_Fa : CLJoined<"Fa">, + HelpText<"Output assembly code to this file during compilation">, + MetaVarName<"<file or directory>">; +def _SLASH_fallback : CLCompileFlag<"fallback">, + HelpText<"Fall back to cl.exe if clang-cl fails to compile">; +def _SLASH_FI : CLJoinedOrSeparate<"FI">, + HelpText<"Include file before parsing">, Alias<include_>; +def _SLASH_Fe : CLJoined<"Fe">, + HelpText<"Set output executable file or directory (ends in / or \\)">, + MetaVarName<"<file or directory>">; +def _SLASH_Fo : CLCompileJoined<"Fo">, + HelpText<"Set output object file, or directory (ends in / or \\)">, + MetaVarName<"<file or directory>">; +def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">; +def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">; +def _SLASH_link : CLRemainingArgs<"link">, + HelpText<"Forward options to the linker">, MetaVarName<"<options>">; +def _SLASH_MD : Option<["/", "-"], "MD", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use DLL run-time">; +def _SLASH_MDd : Option<["/", "-"], "MDd", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use DLL debug run-time">; +def _SLASH_MT : Option<["/", "-"], "MT", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use static run-time">; +def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">; +def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">, + HelpText<"Specify a C source file">, MetaVarName<"<filename>">; +def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">; +def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">, + HelpText<"Specify a C++ source file">, MetaVarName<"<filename>">; +def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">; + + +// Ignored: + +def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">; +def _SLASH_errorReport : CLIgnoredJoined<"errorReport">; +def _SLASH_FS : CLIgnoredFlag<"FS">, HelpText<"Force synchronous PDB writes">; +def _SLASH_GF : CLIgnoredFlag<"GF">; +def _SLASH_GS_ : CLIgnoredFlag<"GS-">; +def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">; +def _SLASH_nologo : CLIgnoredFlag<"nologo">; +def _SLASH_Ob1 : CLIgnoredFlag<"Ob1">; +def _SLASH_Ob2 : CLIgnoredFlag<"Ob2">; +def _SLASH_RTC : CLIgnoredJoined<"RTC">; +def _SLASH_sdl : CLIgnoredFlag<"sdl">; +def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">; +def _SLASH_vmg : CLIgnoredFlag<"vmg">; +def _SLASH_w : CLIgnoredJoined<"w">; +def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">; +def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">; +def _SLASH_Zm : CLIgnoredJoined<"Zm">; + + +// Unsupported: + +def _SLASH_AI : CLJoined<"AI">; +def _SLASH_arch : CLJoined<"arch:">; +def _SLASH_bigobj : CLFlag<"bigobj">; +def _SLASH_clr : CLJoined<"clr">; +def _SLASH_doc : CLJoined<"doc">; +def _SLASH_E : CLFlag<"E">; +def _SLASH_EH : CLJoined<"EH">; +def _SLASH_EP : CLFlag<"EP">; +def _SLASH_FA_joined : CLJoined<"FA">; +def _SLASH_favor : CLJoined<"favor">; +def _SLASH_FC : CLFlag<"FC">; +def _SLASH_F : CLFlag<"F">; +def _SLASH_Fd : CLJoined<"Fd">; +def _SLASH_Fi : CLJoined<"Fi">; +def _SLASH_Fm : CLJoined<"Fm">; +def _SLASH_fp : CLJoined<"fp">; +def _SLASH_Fp : CLJoined<"Fp">; +def _SLASH_Fr : CLJoined<"Fr">; +def _SLASH_FR : CLJoined<"FR">; +def _SLASH_FU : CLJoinedOrSeparate<"FU">; +def _SLASH_Fx : CLFlag<"Fx">; +def _SLASH_G1 : CLFlag<"G1">; +def _SLASH_G2 : CLFlag<"G2">; +def _SLASH_GA : CLFlag<"GA">; +def _SLASH_Gd : CLFlag<"Gd">; +def _SLASH_Ge : CLFlag<"Ge">; +def _SLASH_Gh : CLFlag<"Gh">; +def _SLASH_GH : CLFlag<"GH">; +def _SLASH_GL : CLFlag<"GL">; +def _SLASH_GL_ : CLFlag<"GL-">; +def _SLASH_Gm : CLFlag<"Gm">; +def _SLASH_Gm_ : CLFlag<"Gm-">; +def _SLASH_Gr : CLFlag<"Gr">; +def _SLASH_GS : CLFlag<"GS">; +def _SLASH_Gs : CLJoined<"Gs">; +def _SLASH_GT : CLFlag<"GT">; +def _SLASH_GX : CLFlag<"GX">; +def _SLASH_Gy : CLFlag<"Gy">; +def _SLASH_Gy_ : CLFlag<"Gy-">; +def _SLASH_Gz : CLFlag<"Gz">; +def _SLASH_GZ : CLFlag<"GZ">; +def _SLASH_H : CLFlag<"H">; +def _SLASH_homeparams : CLFlag<"homeparams">; +def _SLASH_hotpatch : CLFlag<"hotpatch">; +def _SLASH_kernel : CLFlag<"kernel">; +def _SLASH_LN : CLFlag<"LN">; +def _SLASH_MP : CLJoined<"MP">; +def _SLASH_o : CLJoinedOrSeparate<"o">; +def _SLASH_openmp : CLFlag<"openmp">; +def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">; +def _SLASH_QIfist : CLFlag<"QIfist">; +def _SLASH_Qimprecise_fwaits : CLFlag<"Qimprecise_fwaits">; +def _SLASH_Qpar : CLFlag<"Qpar">; +def _SLASH_Qvec_report : CLJoined<"Qvec-report">; +def _SLASH_u : CLFlag<"u">; +def _SLASH_V : CLFlag<"V">; +def _SLASH_vd : CLJoined<"vd">; +def _SLASH_vmb : CLFlag<"vmb">; +def _SLASH_vmm : CLFlag<"vmm">; +def _SLASH_vms : CLFlag<"vms">; +def _SLASH_vmv : CLFlag<"vmv">; +def _SLASH_volatile : CLFlag<"volatile">; +def _SLASH_WL : CLFlag<"WL">; +def _SLASH_Wp64 : CLFlag<"Wp64">; +def _SLASH_X : CLFlag<"X">; +def _SLASH_Yc : CLJoined<"Yc">; +def _SLASH_Y_ : CLFlag<"Y-">; +def _SLASH_Yd : CLFlag<"Yd">; +def _SLASH_Yl : CLJoined<"Yl">; +def _SLASH_Yu : CLJoined<"Yu">; +def _SLASH_Z7 : CLFlag<"Z7">; +def _SLASH_Za : CLFlag<"Za">; +def _SLASH_Zc : CLJoined<"Zc:">; +def _SLASH_Ze : CLFlag<"Ze">; +def _SLASH_Zg : CLFlag<"Zg">; +def _SLASH_Zi : CLFlag<"Zi">; +def _SLASH_ZI : CLFlag<"ZI">; +def _SLASH_Zl : CLFlag<"Zl">; +def _SLASH_Zp : CLFlag<"Zp">; +def _SLASH_ZW : CLJoined<"ZW">; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h index 15c5e40..3493e4f 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h @@ -15,11 +15,16 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Path.h" +namespace llvm { +namespace opt { + class DerivedArgList; + class InputArgList; +} +} + namespace clang { namespace driver { - class DerivedArgList; class Driver; - class InputArgList; class JobAction; class JobList; class ToolChain; @@ -34,11 +39,11 @@ class Compilation { const ToolChain &DefaultToolChain; /// The original (untranslated) input argument list. - InputArgList *Args; + llvm::opt::InputArgList *Args; /// The driver translated arguments. Note that toolchains may perform their /// own argument translation. - DerivedArgList *TranslatedArgs; + llvm::opt::DerivedArgList *TranslatedArgs; /// The list of actions. ActionList Actions; @@ -48,11 +53,11 @@ class Compilation { /// Cache of translated arguments for a particular tool chain and bound /// architecture. - llvm::DenseMap<std::pair<const ToolChain*, const char*>, - DerivedArgList*> TCArgs; + llvm::DenseMap<std::pair<const ToolChain *, const char *>, + llvm::opt::DerivedArgList *> TCArgs; /// Temporary files which should be removed on exit. - ArgStringList TempFiles; + llvm::opt::ArgStringList TempFiles; /// Result files which should be removed on failure. ArgStringMap ResultFiles; @@ -62,22 +67,23 @@ class Compilation { ArgStringMap FailureResultFiles; /// Redirection for stdout, stderr, etc. - const llvm::sys::Path **Redirects; + const StringRef **Redirects; public: Compilation(const Driver &D, const ToolChain &DefaultToolChain, - InputArgList *Args, DerivedArgList *TranslatedArgs); + llvm::opt::InputArgList *Args, + llvm::opt::DerivedArgList *TranslatedArgs); ~Compilation(); const Driver &getDriver() const { return TheDriver; } const ToolChain &getDefaultToolChain() const { return DefaultToolChain; } - const InputArgList &getInputArgs() const { return *Args; } + const llvm::opt::InputArgList &getInputArgs() const { return *Args; } - const DerivedArgList &getArgs() const { return *TranslatedArgs; } + const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; } - DerivedArgList &getArgs() { return *TranslatedArgs; } + llvm::opt::DerivedArgList &getArgs() { return *TranslatedArgs; } ActionList &getActions() { return Actions; } const ActionList &getActions() const { return Actions; } @@ -87,7 +93,7 @@ public: void addCommand(Command *C) { Jobs.addJob(C); } - const ArgStringList &getTempFiles() const { return TempFiles; } + const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; } const ArgStringMap &getResultFiles() const { return ResultFiles; } @@ -102,8 +108,8 @@ public: /// 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, - const char *BoundArch); + const llvm::opt::DerivedArgList &getArgsForToolChain(const ToolChain *TC, + const char *BoundArch); /// addTempFile - Add a file to remove on exit, and returns its /// argument. @@ -136,7 +142,7 @@ public: /// /// \param IssueErrors - Report failures as errors. /// \return Whether all files were removed successfully. - bool CleanupFileList(const ArgStringList &Files, + bool CleanupFileList(const llvm::opt::ArgStringList &Files, bool IssueErrors = false) const; /// CleanupFileMap - Remove the files in the given map. @@ -149,23 +155,6 @@ public: const JobAction *JA, bool IssueErrors = false) const; - /// PrintJob - Print one job in -### format. - /// - /// \param OS - The stream to print on. - /// \param J - The job to print. - /// \param Terminator - A string to print at the end of the line. - /// \param Quote - Should separate arguments be quoted. - void PrintJob(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 d9053d1..867444e 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Driver.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Driver.h @@ -15,6 +15,7 @@ #include "clang/Driver/Phases.h" #include "clang/Driver/Types.h" #include "clang/Driver/Util.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" @@ -24,27 +25,41 @@ #include <set> #include <string> +namespace llvm { +namespace opt { + class Arg; + class ArgList; + class DerivedArgList; + class InputArgList; + class OptTable; +} +} + namespace clang { namespace driver { + class Action; - class Arg; - class ArgList; class Command; class Compilation; - class DerivedArgList; - class InputArgList; class InputInfo; class JobAction; - class OptTable; + class SanitizerArgs; class ToolChain; /// Driver - Encapsulate logic for constructing compilation processes /// from a set of gcc-driver-like command line arguments. class Driver { - OptTable *Opts; + llvm::opt::OptTable *Opts; DiagnosticsEngine &Diags; + enum DriverMode { + GCCMode, + GXXMode, + CPPMode, + CLMode + } Mode; + public: // Diag - Forwarding function for diagnostics. DiagnosticBuilder Diag(unsigned DiagID) const { @@ -79,6 +94,9 @@ public: /// sysroot, if present std::string SysRoot; + /// Dynamic loader prefix, if present + std::string DyldPrefix; + /// If the standard library is used bool UseStdLib; @@ -104,16 +122,17 @@ public: const char *CCLogDiagnosticsFilename; /// A list of inputs and their types for the given arguments. - typedef SmallVector<std::pair<types::ID, const Arg*>, 16> InputList; + typedef SmallVector<std::pair<types::ID, const llvm::opt::Arg *>, 16> + InputList; /// Whether the driver should follow g++ like behavior. - unsigned CCCIsCXX : 1; + bool CCCIsCXX() const { return Mode == GXXMode; } /// Whether the driver is just the preprocessor. - unsigned CCCIsCPP : 1; + bool CCCIsCPP() const { return Mode == CPPMode; } - /// Echo commands while executing (in -v style). - unsigned CCCEcho : 1; + /// Whether the driver should follow cl.exe like behavior. + bool IsCLMode() const { return Mode == CLMode; } /// Only print tool bindings, don't build any jobs. unsigned CCCPrintBindings : 1; @@ -163,12 +182,13 @@ private: private: /// TranslateInputArgs - Create a new derived argument list from the input /// arguments, after applying the standard argument translations. - DerivedArgList *TranslateInputArgs(const InputArgList &Args) const; + llvm::opt::DerivedArgList * + TranslateInputArgs(const llvm::opt::InputArgList &Args) const; // getFinalPhase - Determine which compilation mode we are in and record // which option we used to determine the final phase. - phases::ID getFinalPhase(const DerivedArgList &DAL, Arg **FinalPhaseArg = 0) - const; + phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, + llvm::opt::Arg **FinalPhaseArg = 0) const; public: Driver(StringRef _ClangExecutable, @@ -183,8 +203,7 @@ public: /// Name to use when invoking gcc/g++. const std::string &getCCCGenericGCCName() const { return CCCGenericGCCName; } - - const OptTable &getOpts() const { return *Opts; } + const llvm::opt::OptTable &getOpts() const { return *Opts; } const DiagnosticsEngine &getDiags() const { return Diags; } @@ -226,9 +245,12 @@ public: /// @name Driver Steps /// @{ + /// ParseDriverMode - Look for and handle the driver mode option in Args. + void ParseDriverMode(ArrayRef<const char *> Args); + /// ParseArgStrings - Parse the given list of strings into an /// ArgList. - InputArgList *ParseArgStrings(ArrayRef<const char *> Args); + llvm::opt::InputArgList *ParseArgStrings(ArrayRef<const char *> Args); /// BuildInputs - Construct the list of inputs and their types from /// the given arguments. @@ -237,7 +259,7 @@ public: /// \param Args - The input arguments. /// \param Inputs - The list to store the resulting compilation /// inputs onto. - void BuildInputs(const ToolChain &TC, const DerivedArgList &Args, + void BuildInputs(const ToolChain &TC, const llvm::opt::DerivedArgList &Args, InputList &Inputs) const; /// BuildActions - Construct the list of actions to perform for the @@ -246,7 +268,7 @@ public: /// \param TC - The default host tool chain. /// \param Args - The input arguments. /// \param Actions - The list to store the resulting actions onto. - void BuildActions(const ToolChain &TC, const DerivedArgList &Args, + void BuildActions(const ToolChain &TC, llvm::opt::DerivedArgList &Args, const InputList &Inputs, ActionList &Actions) const; /// BuildUniversalActions - Construct the list of actions to perform @@ -255,7 +277,8 @@ public: /// \param TC - The default host tool chain. /// \param Args - The input arguments. /// \param Actions - The list to store the resulting actions onto. - void BuildUniversalActions(const ToolChain &TC, const DerivedArgList &Args, + void BuildUniversalActions(const ToolChain &TC, + llvm::opt::DerivedArgList &Args, const InputList &BAInputs, ActionList &Actions) const; @@ -292,9 +315,6 @@ public: /// \param ShowHidden - Show hidden options. void PrintHelp(bool ShowHidden) const; - /// PrintOptions - Print the list of arguments. - void PrintOptions(const ArgList &Args) const; - /// PrintVersion - Print the driver version. void PrintVersion(const Compilation &C, raw_ostream &OS) const; @@ -324,10 +344,9 @@ public: /// ConstructAction - Construct the appropriate action to do for /// \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 *ConstructPhaseAction(const llvm::opt::ArgList &Args, phases::ID Phase, Action *Input) const; - /// BuildJobsForAction - Construct the jobs to perform for the /// action \p A. void BuildJobsForAction(Compilation &C, @@ -367,18 +386,22 @@ public: /// handle this action. bool ShouldUseClangCompiler(const JobAction &JA) const; - bool IsUsingLTO(const ArgList &Args) const; + bool IsUsingLTO(const llvm::opt::ArgList &Args) const; private: /// \brief Retrieves a ToolChain for a particular target triple. /// /// Will cache ToolChains for the life of the driver object, and create them /// on-demand. - const ToolChain &getToolChain(const ArgList &Args, + const ToolChain &getToolChain(const llvm::opt::ArgList &Args, StringRef DarwinArchName = "") const; /// @} + /// \brief Get bitmasks for which option flags to include and exclude based on + /// the driver mode. + std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks() const; + public: /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and /// return the grouped values as integers. Numbers which are not diff --git a/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h index ea7b52f..f3c33ae 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/DriverDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define DRIVERSTART #include "clang/Basic/DiagnosticDriverKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Job.h b/contrib/llvm/tools/clang/include/clang/Driver/Job.h index 045b5d8..1dd49a7 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Job.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Job.h @@ -11,18 +11,28 @@ #define CLANG_DRIVER_JOB_H_ #include "clang/Basic/LLVM.h" -#include "clang/Driver/Util.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Option/Option.h" + +namespace llvm { + class raw_ostream; +} namespace clang { namespace driver { +class Action; class Command; class Tool; +// Re-export this as clang::driver::ArgStringList. +using llvm::opt::ArgStringList; + class Job { public: enum JobClass { CommandClass, + FallbackCommandClass, JobListClass }; @@ -36,16 +46,19 @@ public: JobClass getKind() const { return Kind; } - /// addCommand - Append a command to the current job, which must be - /// either a piped job or a job list. - void addCommand(Command *C); + /// Print - Print this Job in -### format. + /// + /// \param OS - The stream to print on. + /// \param Terminator - A string to print at the end of the line. + /// \param Quote - Should separate arguments be quoted. + /// \param CrashReport - Whether to print for inclusion in a crash report. + virtual void Print(llvm::raw_ostream &OS, const char *Terminator, + bool Quote, bool CrashReport = false) const = 0; }; - /// Command - An executable path/name and argument vector to - /// execute. +/// Command - An executable path/name and argument vector to +/// execute. class Command : public Job { - virtual void anchor(); - /// Source - The action which caused the creation of this job. const Action &Source; @@ -57,11 +70,17 @@ class Command : public Job { /// The list of program arguments (not including the implicit first /// argument, which will be the executable). - ArgStringList Arguments; + llvm::opt::ArgStringList Arguments; public: Command(const Action &_Source, const Tool &_Creator, const char *_Executable, - const ArgStringList &_Arguments); + const llvm::opt::ArgStringList &_Arguments); + + virtual void Print(llvm::raw_ostream &OS, const char *Terminator, + bool Quote, bool CrashReport = false) const; + + virtual int Execute(const StringRef **Redirects, std::string *ErrMsg, + bool *ExecutionFailed) const; /// getSource - Return the Action which caused the creation of this job. const Action &getSource() const { return Source; } @@ -69,16 +88,37 @@ public: /// getCreator - Return the Tool which caused the creation of this job. const Tool &getCreator() const { return Creator; } - const char *getExecutable() const { return Executable; } + const llvm::opt::ArgStringList &getArguments() const { return Arguments; } - const ArgStringList &getArguments() const { return Arguments; } + static bool classof(const Job *J) { + return J->getKind() == CommandClass || + J->getKind() == FallbackCommandClass; + } +}; + +/// Like Command, but with a fallback which is executed in case +/// the primary command crashes. +class FallbackCommand : public Command { +public: + FallbackCommand(const Action &Source_, const Tool &Creator_, + const char *Executable_, const ArgStringList &Arguments_, + Command *Fallback_); + + virtual void Print(llvm::raw_ostream &OS, const char *Terminator, + bool Quote, bool CrashReport = false) const; + + virtual int Execute(const StringRef **Redirects, std::string *ErrMsg, + bool *ExecutionFailed) const; static bool classof(const Job *J) { - return J->getKind() == CommandClass; + return J->getKind() == FallbackCommandClass; } + +private: + OwningPtr<Command> Fallback; }; - /// JobList - A sequence of jobs to perform. +/// JobList - A sequence of jobs to perform. class JobList : public Job { public: typedef SmallVector<Job*, 4> list_type; @@ -93,6 +133,9 @@ public: JobList(); virtual ~JobList(); + virtual void Print(llvm::raw_ostream &OS, const char *Terminator, + bool Quote, bool CrashReport = false) const; + /// Add a job to the list (taking ownership). void addJob(Job *J) { Jobs.push_back(J); } diff --git a/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td b/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td deleted file mode 100644 index d16a2a7..0000000 --- a/contrib/llvm/tools/clang/include/clang/Driver/OptParser.td +++ /dev/null @@ -1,152 +0,0 @@ -//===--- OptParser.td - Common Option Parsing Interfaces ------------------===// -// -// 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 common interfaces used by the option parsing TableGen -// backend. -// -//===----------------------------------------------------------------------===// - -// Define the kinds of options. - -class OptionKind<string name, int predecence = 0, bit sentinel = 0> { - string Name = name; - // The kind precedence, kinds with lower precedence are matched first. - int Precedence = predecence; - // Indicate a sentinel option. - bit Sentinel = sentinel; -} - -// An option group. -def KIND_GROUP : OptionKind<"Group">; -// The input option kind. -def KIND_INPUT : OptionKind<"Input", 1, 1>; -// The unknown option kind. -def KIND_UNKNOWN : OptionKind<"Unknown", 2, 1>; -// A flag with no values. -def KIND_FLAG : OptionKind<"Flag">; -// An option which prefixes its (single) value. -def KIND_JOINED : OptionKind<"Joined", 1>; -// An option which is followed by its value. -def KIND_SEPARATE : OptionKind<"Separate">; -// An option followed by its values, which are separated by commas. -def KIND_COMMAJOINED : OptionKind<"CommaJoined">; -// An option which is which takes multiple (separate) arguments. -def KIND_MULTIARG : OptionKind<"MultiArg">; -// An option which is either joined to its (non-empty) value, or followed by its -// value. -def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">; -// An option which is both joined to its (first) value, and followed by its -// (second) value. -def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">; - -// Define the option flags. - -class OptionFlag {} - -// DriverOption - The option is a "driver" option, and should not be forwarded -// to gcc. -def DriverOption : OptionFlag; - -// LinkerInput - The option is a linker input. -def LinkerInput : OptionFlag; - -// NoArgumentUnused - Don't report argument unused warnings for this option; this -// is useful for options like -static or -dynamic which a user may always end up -// passing, even if the platform defaults to (or only supports) that option. -def NoArgumentUnused : OptionFlag; - -// RenderAsInput - The option should not render the name when rendered as an -// input (i.e., the option is rendered as values). -def RenderAsInput : OptionFlag; - -// RenderJoined - The option should be rendered joined, even if separate (only -// sensible on single value separate options). -def RenderJoined : OptionFlag; - -// RenderSeparate - The option should be rendered separately, even if joined -// (only sensible on joined options). -def RenderSeparate : OptionFlag; - -// Unsupported - The option is unsupported, and the driver will reject command -// lines that use it. -def Unsupported : OptionFlag; - -// HelpHidden - The option should not be displayed in --help, even if it has -// help text. Clients *can* use this in conjunction with the OptTable::PrintHelp -// arguments to implement hidden help groups. -def HelpHidden : OptionFlag; - -// NoForward - The option should not be implicitly forwarded to other tools. -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> { - string EnumName = ?; // Uses the def name if undefined. - string Name = name; - string HelpText = ?; - OptionGroup Group = ?; -} - -// Define the option class. - -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. - int NumArgs = 0; - string HelpText = ?; - string MetaVarName = ?; - list<OptionFlag> Flags = []; - OptionGroup Group = ?; - Option Alias = ?; -} - -// Helpers for defining options. - -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<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. - -class Alias<Option alias> { Option Alias = alias; } -class EnumName<string name> { string EnumName = name; } -class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; } -class Group<OptionGroup group> { OptionGroup Group = group; } -class HelpText<string text> { string HelpText = text; } -class MetaVarName<string name> { string MetaVarName = name; } - -// Predefined options. - -// 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>; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/OptSpecifier.h b/contrib/llvm/tools/clang/include/clang/Driver/OptSpecifier.h deleted file mode 100644 index e683ef3..0000000 --- a/contrib/llvm/tools/clang/include/clang/Driver/OptSpecifier.h +++ /dev/null @@ -1,41 +0,0 @@ -//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CLANG_DRIVER_OPTSPECIFIER_H -#define CLANG_DRIVER_OPTSPECIFIER_H - -#include "llvm/Support/Compiler.h" - -namespace clang { -namespace driver { - class Option; - - /// OptSpecifier - Wrapper class for abstracting references to option IDs. - class OptSpecifier { - unsigned ID; - - private: - explicit OptSpecifier(bool) LLVM_DELETED_FUNCTION; - - public: - OptSpecifier() : ID(0) {} - /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {} - /*implicit*/ OptSpecifier(const Option *Opt); - - bool isValid() const { return ID != 0; } - - unsigned getID() const { return ID; } - - bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); } - bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); } - }; -} -} - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h b/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h deleted file mode 100644 index 53d83a0..0000000 --- a/contrib/llvm/tools/clang/include/clang/Driver/OptTable.h +++ /dev/null @@ -1,161 +0,0 @@ -//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CLANG_DRIVER_OPTTABLE_H -#define CLANG_DRIVER_OPTTABLE_H - -#include "clang/Basic/LLVM.h" -#include "clang/Driver/OptSpecifier.h" -#include "llvm/ADT/StringSet.h" - -namespace clang { -namespace driver { - class Arg; - class ArgList; - class InputArgList; - class Option; - - /// \brief Provide access to the Option info table. - /// - /// The OptTable class provides a layer of indirection which allows Option - /// instance to be created lazily. In the common case, only a few options will - /// be needed at runtime; the OptTable class maintains enough information to - /// parse command lines without instantiating Options, while letting other - /// parts of the driver still use Option instances where convenient. - class OptTable { - 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; - unsigned short GroupID; - unsigned short AliasID; - }; - - private: - /// \brief The static option information table. - const Info *OptionInfos; - unsigned NumOptionInfos; - - 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(); - assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID."); - return OptionInfos[id - 1]; - } - - protected: - OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos); - public: - ~OptTable(); - - /// \brief Return the total number of option classes. - unsigned getNumOptions() const { return NumOptionInfos; } - - /// \brief Get the given Opt's Option instance, lazily creating it - /// if necessary. - /// - /// \return The option, or null for the INVALID option id. - const Option getOption(OptSpecifier Opt) const; - - /// \brief Lookup the name of the given option. - const char *getOptionName(OptSpecifier id) const { - return getInfo(id).Name; - } - - /// \brief Get the kind of the given option. - unsigned getOptionKind(OptSpecifier id) const { - return getInfo(id).Kind; - } - - /// \brief Get the group id for the given option. - unsigned getOptionGroupID(OptSpecifier id) const { - return getInfo(id).GroupID; - } - - /// \brief Get the help text to use to describe this option. - const char *getOptionHelpText(OptSpecifier id) const { - return getInfo(id).HelpText; - } - - /// \brief Get the meta-variable name to use when describing - /// this options values in the help text. - const char *getOptionMetaVar(OptSpecifier id) const { - return getInfo(id).MetaVar; - } - - /// \brief Parse a single argument; returning the new argument and - /// updating Index. - /// - /// \param [in,out] Index - The current parsing position in the argument - /// string list; on return this will be the index of the next argument - /// string to parse. - /// - /// \return The parsed argument, or 0 if the argument is missing values - /// (in which case Index still points at the conceptual next argument string - /// to parse). - Arg *ParseOneArg(const ArgList &Args, unsigned &Index) const; - - /// \brief Parse an list of arguments into an InputArgList. - /// - /// The resulting InputArgList will reference the strings in [\p ArgBegin, - /// \p ArgEnd), and their lifetime should extend past that of the returned - /// InputArgList. - /// - /// The only error that can occur in this routine is if an argument is - /// missing values; in this case \p MissingArgCount will be non-zero. - /// - /// \param ArgBegin - The beginning of the argument vector. - /// \param ArgEnd - The end of the argument vector. - /// \param MissingArgIndex - On error, the index of the option which could - /// not be parsed. - /// \param MissingArgCount - On error, the number of missing options. - /// \return An InputArgList; on error this will contain all the options - /// which could be parsed. - InputArgList *ParseArgs(const char* const *ArgBegin, - const char* const *ArgEnd, - unsigned &MissingArgIndex, - unsigned &MissingArgCount) const; - - /// \brief Render the help text for an option table. - /// - /// \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 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, unsigned short FlagsToInclude = 0, - unsigned short FlagsToExclude = 0) const; - }; -} -} - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Option.h b/contrib/llvm/tools/clang/include/clang/Driver/Option.h deleted file mode 100644 index 764934f..0000000 --- a/contrib/llvm/tools/clang/include/clang/Driver/Option.h +++ /dev/null @@ -1,204 +0,0 @@ -//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CLANG_DRIVER_OPTION_H_ -#define CLANG_DRIVER_OPTION_H_ - -#include "clang/Basic/LLVM.h" -#include "clang/Driver/OptTable.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/ErrorHandling.h" - -namespace clang { -namespace driver { - class Arg; - class ArgList; - -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. - /// - /// An Option class represents a form of option that the driver - /// takes, for example how many arguments the option has and how - /// they can be provided. Individual option instances store - /// additional information about what group the option is a member - /// of (if any), if the option is an alias, and a number of - /// flags. At runtime the driver parses the command line into - /// concrete Arg instances, each of which corresponds to a - /// particular Option instance. - class Option { - public: - enum OptionClass { - GroupClass = 0, - InputClass, - UnknownClass, - FlagClass, - JoinedClass, - SeparateClass, - CommaJoinedClass, - MultiArgClass, - JoinedOrSeparateClass, - JoinedAndSeparateClass - }; - - enum RenderStyleKind { - RenderCommaJoinedStyle, - RenderJoinedStyle, - RenderSeparateStyle, - RenderValuesStyle - }; - - protected: - const OptTable::Info *Info; - const OptTable *Owner; - - public: - Option(const OptTable::Info *Info, const OptTable *Owner); - ~Option(); - - bool isValid() const { - return Info != 0; - } - - unsigned getID() const { - assert(Info && "Must have a valid info!"); - return Info->ID; - } - - OptionClass getKind() const { - assert(Info && "Must have a valid info!"); - return OptionClass(Info->Kind); - } - - /// \brief Get the name of this option without any prefix. - StringRef getName() const { - assert(Info && "Must have a valid info!"); - return Info->Name; - } - - const Option getGroup() const { - assert(Info && "Must have a valid info!"); - assert(Owner && "Must have a valid owner!"); - return Owner->getOption(Info->GroupID); - } - - const Option getAlias() const { - assert(Info && "Must have a valid info!"); - assert(Owner && "Must have a valid owner!"); - return Owner->getOption(Info->AliasID); - } - - /// \brief Get the default prefix for this option. - StringRef getPrefix() const { - const char *Prefix = *Info->Prefixes; - return Prefix ? Prefix : StringRef(); - } - - /// \brief Get the name of this option with the default prefix. - std::string getPrefixedName() const { - std::string Ret = getPrefix(); - Ret += getName(); - return Ret; - } - - unsigned getNumArgs() const { return Info->Param; } - - bool hasNoOptAsInput() const { return Info->Flags & options::RenderAsInput;} - - RenderStyleKind getRenderStyle() const { - 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!"); - } - - /// 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 { - 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(); - } - - /// matches - Predicate for whether this option is part of the - /// given option (which may be a group). - /// - /// Note that matches against options which are an alias should never be - /// done -- aliases do not participate in matching and so such a query will - /// always be false. - bool matches(OptSpecifier ID) const; - - /// accept - Potentially accept the current argument, returning a - /// new Arg instance, or 0 if the option does not accept this - /// argument (or the argument is missing values). - /// - /// 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). - /// - /// \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; - }; - -} // end namespace driver -} // end namespace clang - -#endif diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Options.h b/contrib/llvm/tools/clang/include/clang/Driver/Options.h index 6c114e2..28948be 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Options.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Options.h @@ -10,24 +10,40 @@ #ifndef CLANG_DRIVER_OPTIONS_H #define CLANG_DRIVER_OPTIONS_H +namespace llvm { +namespace opt { +class OptTable; +} +} + namespace clang { namespace driver { - class OptTable; namespace options { - enum ID { +/// Flags specifically for clang options. Must not overlap with +/// llvm::opt::DriverFlag. +enum ClangFlags { + DriverOption = (1 << 4), + LinkerInput = (1 << 5), + NoArgumentUnused = (1 << 6), + Unsupported = (1 << 7), + CoreOption = (1 << 8), + CLOption = (1 << 9), + CC1Option = (1 << 10), + NoDriverOption = (1 << 11) +}; + +enum ID { OPT_INVALID = 0, // This is not an option ID. -#define PREFIX(NAME, VALUE) -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR) OPT_##ID, #include "clang/Driver/Options.inc" LastOption #undef OPTION -#undef PREFIX }; } - OptTable *createDriverOptTable(); +llvm::opt::OptTable *createDriverOptTable(); } } diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Options.td b/contrib/llvm/tools/clang/include/clang/Driver/Options.td index e0ce94d..ccfdf74 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Options.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/Options.td @@ -12,23 +12,55 @@ //===----------------------------------------------------------------------===// // Include the common option parsing interfaces. -include "OptParser.td" +include "llvm/Option/OptParser.td" + +///////// +// Flags + +// DriverOption - The option is a "driver" option, and should not be forwarded +// to other tools. +def DriverOption : OptionFlag; + +// LinkerInput - The option is a linker input. +def LinkerInput : OptionFlag; + +// NoArgumentUnused - Don't report argument unused warnings for this option; this +// is useful for options like -static or -dynamic which a user may always end up +// passing, even if the platform defaults to (or only supports) that option. +def NoArgumentUnused : OptionFlag; + +// Unsupported - The option is unsupported, and the driver will reject command +// lines that use it. +def Unsupported : OptionFlag; + +// CoreOption - This is considered a "core" Clang option, available in both +// clang and clang-cl modes. +def CoreOption : OptionFlag; + +// CLOption - This is a cl.exe compatibility option. Options with this flag +// are made available when the driver is running in CL compatibility mode. +def CLOption : 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; ///////// // Groups -// Meta-group which defines +// Meta-group for options which are only used for compilation, +// and not linking etc. def CompileOnly_Group : OptionGroup<"<CompileOnly group>">; + def Action_Group : OptionGroup<"<action group>">; def I_Group : OptionGroup<"<I group>">, Group<CompileOnly_Group>; -def L_Group : OptionGroup<"<L group>">, Group<CompileOnly_Group>; def M_Group : OptionGroup<"<M group>">, Group<CompileOnly_Group>; def T_Group : OptionGroup<"<T group>">; def O_Group : OptionGroup<"<O group>">, Group<CompileOnly_Group>; def W_Group : OptionGroup<"<W group>">, Group<CompileOnly_Group>; -def X_Group : OptionGroup<"<X group>">; -def a_Group : OptionGroup<"<a group>">; def d_Group : OptionGroup<"<d group>">; def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>; def f_clang_Group : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>; @@ -39,10 +71,10 @@ def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>; def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>; def m_x86_Features_Group : OptionGroup<"<m x86 features group>">, Group<m_Group>; def m_hexagon_Features_Group : OptionGroup<"<m hexagon features group>">, Group<m_Group>; +def m_arm_Features_Group : OptionGroup<"<m arm features group>">, Group<m_Group>; +def m_ppc_Features_Group : OptionGroup<"<m ppc 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>; @@ -69,7 +101,9 @@ def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">, // substitutions: // _ => __ // - => _ +// / => _SLASH // # => _HASH +// ? => _QUESTION // , => _COMMA // = => _EQ // C++ => CXX @@ -77,45 +111,40 @@ def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">, // Developer Driver Options -def ccc_Group : OptionGroup<"<clang internal options>">; -def ccc_driver_Group : OptionGroup<"<clang driver internal options>">, - Group<ccc_Group>, HelpText<"DRIVER OPTIONS">; -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, - HelpText<"Act as a C++ driver">; -def ccc_echo : Flag<["-"], "ccc-echo">, CCCDriverOpt, - HelpText<"Echo commands before running them">; -def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, CCCDriverOpt, +def internal_Group : OptionGroup<"<clang internal options>">; +def internal_driver_Group : OptionGroup<"<clang driver internal options>">, + Group<internal_Group>, HelpText<"DRIVER OPTIONS">; +def internal_debug_Group : + OptionGroup<"<clang debug/development internal options>">, + Group<internal_Group>, HelpText<"DEBUG/DEVELOPMENT OPTIONS">; + +class InternalDriverOpt : Group<internal_driver_Group>, + Flags<[DriverOption, HelpHidden]>; +def driver_mode : Joined<["--"], "driver-mode=">, Group<internal_driver_Group>, + Flags<[CoreOption, DriverOption, HelpHidden]>, + HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">; +def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, InternalDriverOpt, HelpText<"Name for native GCC compiler">, MetaVarName<"<gcc-path>">; -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">, InternalDriverOpt, 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">, InternalDriverOpt, 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, +class InternalDebugOpt : Group<internal_debug_Group>, + Flags<[DriverOption, HelpHidden]>; +def ccc_install_dir : Separate<["-"], "ccc-install-dir">, InternalDebugOpt, HelpText<"Simulate installation in the given directory">; -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">, InternalDebugOpt, HelpText<"Dump list of actions to perform">; -def ccc_print_bindings : Flag<["-"], "ccc-print-bindings">, CCCDebugOpt, +def ccc_print_bindings : Flag<["-"], "ccc-print-bindings">, InternalDebugOpt, HelpText<"Show bindings of tools to actions">; -def ccc_arcmt_check : Flag<["-"], "ccc-arcmt-check">, CCCDriverOpt, +def ccc_arcmt_check : Flag<["-"], "ccc-arcmt-check">, InternalDriverOpt, 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">, InternalDriverOpt, 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_arcmt_migrate : Separate<["-"], "ccc-arcmt-migrate">, InternalDriverOpt, HelpText<"Apply modifications and produces temporary files that conform to ARC">; def arcmt_migrate_report_output : Separate<["-"], "arcmt-migrate-report-output">, HelpText<"Output path for the plist report">, Flags<[CC1Option]>; @@ -125,25 +154,49 @@ def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">, 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">, + InternalDriverOpt, HelpText<"Apply modifications and produces temporary files to migrate to " "modern ObjC syntax">; 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]>, HelpText<"Enable migration to modern ObjC subscripting">; +def objcmt_migrate_property : Flag<["-"], "objcmt-migrate-property">, Flags<[CC1Option]>, + HelpText<"Enable migration to modern ObjC property">; +def objcmt_migrate_all : Flag<["-"], "objcmt-migrate-all">, Flags<[CC1Option]>, + HelpText<"Enable migration to modern ObjC">; +def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-property">, Flags<[CC1Option]>, + HelpText<"Enable migration to modern ObjC readonly property">; +def objcmt_migrate_readwrite_property : Flag<["-"], "objcmt-migrate-readwrite-property">, Flags<[CC1Option]>, + HelpText<"Enable migration to modern ObjC readwrite property">; +def objcmt_migrate_annotation : Flag<["-"], "objcmt-migrate-annotation">, Flags<[CC1Option]>, + HelpText<"Enable migration to property and method annotations">; +def objcmt_migrate_instancetype : Flag<["-"], "objcmt-migrate-instancetype">, Flags<[CC1Option]>, + HelpText<"Enable migration to infer instancetype for method result type">; +def objcmt_migrate_nsmacros : Flag<["-"], "objcmt-migrate-ns-macros">, Flags<[CC1Option]>, + HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">; +def objcmt_migrate_protocol_conformance : Flag<["-"], "objcmt-migrate-protocol-conformance">, Flags<[CC1Option]>, + HelpText<"Enable migration to add protocol conformance on classes">; +def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">, Flags<[CC1Option]>, + HelpText<"Make migration to 'atomic' properties">; +def objcmt_returns_innerpointer_property : Flag<["-"], "objcmt-returns-innerpointer-property">, Flags<[CC1Option]>, + HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">; +def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, Flags<[CC1Option]>, + HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">; +def objcmt_white_list_dir_path: Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>, + HelpText<"Only modify files with a filename contained in the provided directory path">; // Make sure all other -ccc- options are rejected. -def ccc_ : Joined<["-"], "ccc-">, Group<ccc_Group>, Flags<[Unsupported]>; +def ccc_ : Joined<["-"], "ccc-">, Group<internal_Group>, Flags<[Unsupported]>; // Standard Options -def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[DriverOption]>, +def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[DriverOption, CoreOption]>, 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 _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>, + Flags<[DriverOption, CoreOption]>; +def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>; def B : JoinedOrSeparate<["-"], "B">; def CC : Flag<["-"], "CC">, Flags<[CC1Option]>; def C : Flag<["-"], "C">, Flags<[CC1Option]>; @@ -174,18 +227,19 @@ 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 O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>; +def O4 : Flag<["-"], "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]>, HelpText<"Treat source input files as Objective-C inputs">; def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option]>; +def O_flag : Flag<["-"], "O">, Flags<[CC1Option]>, Alias<O>, AliasArgs<["2"]>; def Ofast : Joined<["-"], "Ofast">, 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 Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption, CoreOption]>, HelpText<"Don't emit warning for unused driver arguments">; def Q : Flag<["-"], "Q">; def R : Flag<["-"], "R">; @@ -214,9 +268,7 @@ def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group<W_Gr 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 W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>, MetaVarName<"<warning>">, HelpText<"Enable the specified warning">; def Xanalyzer : Separate<["-"], "Xanalyzer">, HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">; @@ -225,7 +277,7 @@ def Xassembler : Separate<["-"], "Xassembler">, HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">; def Xclang : Separate<["-"], "Xclang">, HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">, - Flags<[NoForward]>; + Flags<[DriverOption, CoreOption]>; def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>, HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">; def Xpreprocessor : Separate<["-"], "Xpreprocessor">, @@ -236,11 +288,11 @@ 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 ansi : Flag<["-", "--"], "ansi">; 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 a : Joined<["-"], "a">; def bind__at__load : Flag<["-"], "bind_at_load">; def bundle__loader : Separate<["-"], "bundle_loader">; def bundle : Flag<["-"], "bundle">; @@ -290,9 +342,6 @@ 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 fno_altivec : Flag<["-"], "fno-altivec">, 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]>, @@ -313,9 +362,14 @@ def fast : Flag<["-"], "fast">, Group<f_Group>; def fasynchronous_unwind_tables : Flag<["-"], "fasynchronous-unwind-tables">, Group<f_Group>; def fautolink : Flag <["-"], "fautolink">, Group<f_Group>; -def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>, Flags<[NoForward, CC1Option]>, +def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>, + Flags<[DriverOption, CC1Option]>, HelpText<"Disable generation of linker directives for automatic library linking">; +def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">, + Group<f_Group>, Flags<[DriverOption, CC1Option]>, + HelpText<"Enable sample-based profile guided optimizations">; + def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable the 'blocks' language feature">; def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>; @@ -325,8 +379,6 @@ 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">, Group<f_Group>; @@ -335,6 +387,8 @@ def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, Flag HelpText<"Use colors in diagnostics">; def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<f_Group>; def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group<f_Group>; +def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Use ANSI escape codes for diagnostics">; def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">, MetaVarName<"<arg>">; @@ -344,13 +398,15 @@ 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_steps_EQ : Joined<["-"], "fconstexpr-steps=">, 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>, HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>; -def fcxx_modules : Flag <["-"], "fcxx-modules">, Group<f_Group>, Flags<[NoForward]>; +def fcxx_modules : Flag <["-"], "fcxx-modules">, Group<f_Group>, + Flags<[DriverOption]>; 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>; @@ -387,6 +443,10 @@ 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 fexpensive_optimizations : Flag<["-"], "fexpensive-optimizations">, + Group<clang_ignored_f_Group>; +def fno_expensive_optimizations : Flag<["-"], "fno-expensive-optimizations">, + Group<clang_ignored_f_Group>; def fextdirs_EQ : Joined<["-"], "fextdirs=">, Group<f_Group>; def fextended_identifiers : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>; @@ -405,7 +465,7 @@ def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, 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>">, + Flags<[CC1Option, CoreOption]>, MetaVarName<"<check>">, HelpText<"Enable runtime instrumentation for bug detection: " "address (memory errors) | thread (race detection) | " "undefined (miscellaneous undefined behavior)">; @@ -502,13 +562,13 @@ def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Op HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">; def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable Microsoft compatibility mode">; -def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[CC1Option]>, +def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>, HelpText<"Version of the Microsoft C/C++ compiler to report in _MSC_VER (0 = don't define it (default))">; 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 fmodules_cache_path : Joined<["-"], "fmodules-cache-path=">, Group<i_Group>, - Flags<[NoForward,CC1Option]>, MetaVarName<"<directory>">, + Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">, HelpText<"Specify the module cache path">; def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>, Flags<[CC1Option]>, MetaVarName<"<seconds>">, @@ -516,10 +576,23 @@ def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i def fmodules_prune_after : Joined<["-"], "fmodules-prune-after=">, Group<i_Group>, Flags<[CC1Option]>, MetaVarName<"<seconds>">, HelpText<"Specify the interval (in seconds) after which a module file will be considered unused">; -def fmodules : Flag <["-"], "fmodules">, Group<f_Group>, Flags<[NoForward,CC1Option]>, +def fmodules : Flag <["-"], "fmodules">, Group<f_Group>, + Flags<[DriverOption, CC1Option]>, HelpText<"Enable the 'modules' language feature">; +def fmodule_maps : Flag <["-"], "fmodule-maps">, Group<f_Group>, + Flags<[DriverOption,CC1Option]>, + HelpText<"Read module maps to understand the structure of library headers">; +def fmodule_name : JoinedOrSeparate<["-"], "fmodule-name=">, Group<f_Group>, + Flags<[DriverOption,CC1Option]>, MetaVarName<"<name>">, + HelpText<"Specify the name of the module to build">; +def fmodule_map_file : JoinedOrSeparate<["-"], "fmodule-map-file=">, + Group<f_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"<file>">, + HelpText<"Load this module map file">; def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Ignore the definition of the given macro when building and loading modules">; +def fmodules_decluse : Flag <["-"], "fmodules-decluse">, Group<f_Group>, + Flags<[DriverOption,CC1Option]>, + HelpText<"Require declaration of modules used within a module">; def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>; def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>; @@ -536,10 +609,12 @@ def fno_assume_sane_operator_new : Flag<["-"], "fno-assume-sane-operator-new">, 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_builtin_ : Joined<["-"], "fno-builtin-">, Group<clang_ignored_f_Group>, + HelpText<"Disable implicit builtin knowledge of a specific function">; +def fno_math_builtin : Flag<["-"], "fno-math-builtin">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Disable implicit builtin knowledge of math functions">; def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<f_Group>, Flags<[CC1Option]>; def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<f_Group>; @@ -550,13 +625,14 @@ def fno_constant_cfstrings : Flag<["-"], "fno-constant-cfstrings">, Group<f_Grou 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_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group<f_Group>, + Flags<[DriverOption]>; def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">; def fno_diagnostics_show_name : Flag<["-"], "fno-diagnostics-show-name">, Group<f_Group>; def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>; def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">, - Flags<[CC1Option]>, Group<f_Group>, HelpText<"Display include stacks for diagnostic notes">; + Flags<[CC1Option]>, 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>, @@ -573,7 +649,12 @@ def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Group<f_Group>, 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_modules : Flag <["-"], "fno-modules">, Group<f_Group>, + Flags<[DriverOption]>; +def fno_module_maps : Flag <["-"], "fno-module-maps">, Group<f_Group>, + Flags<[DriverOption]>; +def fno_modules_decluse : Flag <["-"], "fno-modules-decluse">, Group<f_Group>, + Flags<[DriverOption]>; def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>; def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>; def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>; @@ -596,6 +677,7 @@ def fno_spell_checking : Flag<["-"], "fno-spell-checking">, 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 fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>; +def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>; def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>; def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>; def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>, @@ -645,7 +727,6 @@ 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>, Flags<[CC1Option]>; def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>; @@ -660,6 +741,8 @@ def fpack_struct_EQ : Joined<["-"], "fpack-struct=">, Group<f_Group>, Flags<[CC1 HelpText<"Specify the default maximum struct packing alignment">; def fpascal_strings : Flag<["-"], "fpascal-strings">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Recognize and construct Pascal-style string literals">; +def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Override the default ABI to return all structs on the stack">; 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>; @@ -669,6 +752,8 @@ 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 freg_struct_return : Flag<["-"], "freg-struct-return">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Override the default ABI to return small structs in registers">; def frtti : Flag<["-"], "frtti">, Group<f_Group>; def fsched_interblock : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>; def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>, Flags<[CC1Option]>, @@ -684,6 +769,8 @@ 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 fno_signed_char : Flag<["-"], "fno-signed-char">, Flags<[CC1Option]>, + Group<clang_ignored_f_Group>, HelpText<"Char is unsigned">; def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>; def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>; @@ -698,6 +785,8 @@ 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 foperator_arrow_depth_EQ : Joined<["-"], "foperator-arrow-depth=">, + Group<f_Group>; def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>; def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>, HelpText<"Enable the loop vectorization passes">; @@ -739,12 +828,21 @@ def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group<f_Group>, Flags< 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 fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>, + HelpText<"Turn off loop unroller">, Flags<[CC1Option]>; +def freroll_loops : Flag<["-"], "freroll-loops">, Group<f_Group>, + HelpText<"Turn on loop reroller">, Flags<[CC1Option]>; +def fno_reroll_loops : Flag<["-"], "fno-reroll-loops">, Group<f_Group>, + HelpText<"Turn off loop reroller">; def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>; def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>; +def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">, Group<clang_ignored_f_Group>; def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>; def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group<f_Group>; def fuse_init_array : Flag<["-"], "fuse-init-array">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use .init_array instead of .ctors">; +def fno_var_tracking : Flag<["-"], "fno-var-tracking">, + Group<clang_ignored_f_Group>; def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>; def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>, HelpText<"Set the default symbol visibility for all global declarations">; @@ -759,11 +857,17 @@ def fwrapv : Flag<["-"], "fwrapv">, 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>, - Flags<[CC1Option]>, HelpText<"Place each function in its own section (ELF Only)">; -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 ffunction_sections : Flag<["-"], "ffunction-sections">, Group<f_Group>, + Flags<[CC1Option]>, + HelpText<"Place each function in its own section (ELF Only)">; +def fno_function_sections : Flag<["-"], "fno-function-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 fno_data_sections : Flag <["-"], "fno-data-sections">, Group<f_Group>, + Flags<[CC1Option]>; +def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>, + Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">; def 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>, @@ -777,9 +881,12 @@ 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 gdwarf_2 : Flag<["-"], "gdwarf-2">, Group<g_Group>, + HelpText<"Generate source level debug information with dwarf version 2">, Flags<[CC1Option]>; +def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group<g_Group>, + HelpText<"Generate source level debug information with dwarf version 3">, Flags<[CC1Option]>; +def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>, + HelpText<"Generate source level debug information with dwarf version 4">, Flags<[CC1Option]>; def gfull : Flag<["-"], "gfull">, Group<g_Group>; def gused : Flag<["-"], "gused">, Group<g_Group>; def gstabs : Joined<["-"], "gstabs">, Group<g_Group>, Flags<[Unsupported]>; @@ -794,6 +901,7 @@ 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 gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>; +def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>; def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">; def help : Flag<["-", "--"], "help">, Flags<[CC1Option]>, HelpText<"Display available options">; @@ -810,6 +918,8 @@ def include_ : JoinedOrSeparate<["-", "--"], "include">, Group<clang_i_Group>, E MetaVarName<"<file>">, HelpText<"Include file before parsing">, Flags<[CC1Option]>; def include_pch : Separate<["-"], "include-pch">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Include precompiled header file">, MetaVarName<"<file>">; +def relocatable_pch : Flag<["-", "--"], "relocatable-pch">, Flags<[CC1Option]>, + HelpText<"Whether to build a relocatable precompiled header">; def init : Separate<["-"], "init">; def install__name : Separate<["-"], "install_name">; def integrated_as : Flag<["-"], "integrated-as">, Flags<[DriverOption]>; @@ -837,39 +947,34 @@ def lazy__framework : Separate<["-"], "lazy_framework">, Flags<[LinkerInput]>; def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>; def EL : Flag<["-"], "EL">, Flags<[DriverOption]>; def EB : Flag<["-"], "EB">, Flags<[DriverOption]>; -def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[DriverOption]>; +def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>; def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>, Flags<[DriverOption,CC1Option]>, HelpText<"Enable hexagon-qdsp6 backward compatibility">; 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 m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption, CoreOption]>; def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>; def march_EQ : Joined<["-"], "march=">, Group<m_Group>; -def maltivec : Flag<["-"], "maltivec">, Alias<faltivec>; -def mno_altivec : Flag<["-"], "mno-altivec">, Alias<fno_altivec>; -def mfprnd : Flag<["-"], "mfprnd">, Group<m_Group>; -def mno_fprnd : Flag<["-"], "mno-fprnd">, Group<m_Group>; -def mmfcrf : Flag<["-"], "mmfcrf">, Group<m_Group>; -def mno_mfcrf : Flag<["-"], "mno-mfcrf">, Group<m_Group>; -def mpopcntd : Flag<["-"], "mpopcntd">, Group<m_Group>; -def mno_popcntd : Flag<["-"], "mno-popcntd">, Group<m_Group>; -def mqpx : Flag<["-"], "mqpx">, Group<m_Group>; -def mno_qpx : Flag<["-"], "mno-qpx">, Group<m_Group>; 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 mieee_fp : Flag<["-"], "mieee-fp">, Group<clang_ignored_m_Group>; +def minline_all_stringops : Flag<["-"], "minline-all-stringops">, Group<clang_ignored_m_Group>; +def mno_inline_all_stringops : Flag<["-"], "mno-inline-all-stringops">, 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 mhwdiv_EQ : Joined<["-"], "mhwdiv=">, 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 mlinker_version_EQ : Joined<["-"], "mlinker-version=">, + Flags<[DriverOption]>; 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>; @@ -879,8 +984,6 @@ def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>, Flags<[CC1Opti 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 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>; @@ -888,7 +991,8 @@ def mno_constant_cfstrings : Flag<["-"], "mno-constant-cfstrings">, Group<m_Grou 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_pascal_strings : Flag<["-"], "mno-pascal-strings">, + Alias<fno_pascal_strings>; 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>; @@ -905,12 +1009,17 @@ 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_avx512f : Flag<["-"], "mno-avx512f">, Group<m_x86_Features_Group>; +def mno_avx512cd : Flag<["-"], "mno-avx512cd">, Group<m_x86_Features_Group>; +def mno_avx512er : Flag<["-"], "mno-avx512er">, Group<m_x86_Features_Group>; +def mno_avx512pf : Flag<["-"], "mno-avx512pf">, 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_tbm : Flag<["-"], "mno-tbm">, 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>; @@ -918,16 +1027,50 @@ def mno_f16c : Flag<["-"], "mno-f16c">, Group<m_x86_Features_Group>; def mno_rtm : Flag<["-"], "mno-rtm">, Group<m_x86_Features_Group>; def mno_prfchw : Flag<["-"], "mno-prfchw">, Group<m_x86_Features_Group>; def mno_rdseed : Flag<["-"], "mno-rdseed">, Group<m_x86_Features_Group>; +def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>; -def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_Group>; +def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>, + HelpText<"Allow memory accesses to be unaligned (ARM only)">; +def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group<m_arm_Features_Group>, + HelpText<"Force all memory accesses to be aligned (ARM only)">; +def mstrict_align : Flag<["-"], "mstrict-align">, Alias<mno_unaligned_access>, Flags<[CC1Option,HelpHidden]>, + HelpText<"Force all memory accesses to be aligned (ARM only, same as mno-unaligned-access)">; +def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_arm_Features_Group>; +def mrestrict_it: Flag<["-"], "mrestrict-it">, Group<m_arm_Features_Group>, + HelpText<"Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.">; +def mno_restrict_it: Flag<["-"], "mno-restrict-it">, Group<m_arm_Features_Group>, + HelpText<"Allow generation of deprecated IT blocks for ARMv8. It is off by default for ARMv8 Thumb mode">; def marm : Flag<["-"], "marm">, Alias<mno_thumb>; +def ffixed_r9 : Flag<["-"], "ffixed-r9">, Group<m_arm_Features_Group>, + HelpText<"Reserve the r9 register (ARM only)">; +def mcrc : Flag<["-"], "mcrc">, Group<m_arm_Features_Group>, + HelpText<"Allow use of CRC instructions (ARM only)">; +def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>, + HelpText<"Disallow use of CRC instructions (ARM only)">; + +def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>; +def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>; +def mfprnd : Flag<["-"], "mfprnd">, Group<m_ppc_Features_Group>; +def mno_fprnd : Flag<["-"], "mno-fprnd">, Group<m_ppc_Features_Group>; +def mmfcrf : Flag<["-"], "mmfcrf">, Group<m_ppc_Features_Group>; +def mno_mfcrf : Flag<["-"], "mno-mfcrf">, Group<m_ppc_Features_Group>; +def mpopcntd : Flag<["-"], "mpopcntd">, Group<m_ppc_Features_Group>; +def mno_popcntd : Flag<["-"], "mno-popcntd">, Group<m_ppc_Features_Group>; +def mqpx : Flag<["-"], "mqpx">, Group<m_ppc_Features_Group>; +def mno_qpx : Flag<["-"], "mno-qpx">, Group<m_ppc_Features_Group>; + +def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Enable AltiVec vector initializer syntax">; +def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[CC1Option]>; +def maltivec : Flag<["-"], "maltivec">, Alias<faltivec>; +def mno_altivec : Flag<["-"], "mno-altivec">, Alias<fno_altivec>; 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 moslib_EQ : Joined<["-"], "moslib=">, Group<m_Group>; -def mpascal_strings : Flag<["-"], "mpascal-strings">, Group<m_Group>; +def mpascal_strings : Flag<["-"], "mpascal-strings">, Alias<fpascal_strings>; 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]>, @@ -951,12 +1094,17 @@ 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 mavx512f : Flag<["-"], "mavx512f">, Group<m_x86_Features_Group>; +def mavx512cd : Flag<["-"], "mavx512cd">, Group<m_x86_Features_Group>; +def mavx512er : Flag<["-"], "mavx512er">, Group<m_x86_Features_Group>; +def mavx512pf : Flag<["-"], "mavx512pf">, 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 mtbm : Flag<["-"], "mtbm">, 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>; @@ -964,25 +1112,45 @@ def mf16c : Flag<["-"], "mf16c">, Group<m_x86_Features_Group>; def mrtm : Flag<["-"], "mrtm">, Group<m_x86_Features_Group>; def mprfchw : Flag<["-"], "mprfchw">, Group<m_x86_Features_Group>; def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>; +def msha : Flag<["-"], "msha">, Group<m_x86_Features_Group>; +def mcx16 : Flag<["-"], "mcx16">, Group<m_x86_Features_Group>; def mips16 : Flag<["-"], "mips16">, Group<m_Group>; def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>; def mmicromips : Flag<["-"], "mmicromips">, Group<m_Group>; def mno_micromips : Flag<["-"], "mno-micromips">, Group<m_Group>; def mxgot : Flag<["-"], "mxgot">, Group<m_Group>; def mno_xgot : Flag<["-"], "mno-xgot">, Group<m_Group>; +def mldc1_sdc1 : Flag<["-"], "mldc1-sdc1">, Group<m_Group>; +def mno_ldc1_sdc1 : Flag<["-"], "mno-ldc1-sdc1">, Group<m_Group>; +def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">, Group<m_Group>; +def mno_check_zero_division : Flag<["-"], "mno-check-zero-division">, + 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 msingle_float : Flag<["-"], "msingle-float">, Group<m_Group>; def mdouble_float : Flag<["-"], "mdouble-float">, Group<m_Group>; -def mips32 : Flag<["-"], "mips32">, Group<mips_CPUs_Group>, +def mmsa : Flag<["-"], "mmsa">, Group<m_Group>, + HelpText<"Enable MSA ASE (MIPS only)">; +def mno_msa : Flag<["-"], "mno-msa">, Group<m_Group>, + HelpText<"Disable MSA ASE (MIPS only)">; +def mfp64 : Flag<["-"], "mfp64">, Group<m_Group>, + HelpText<"Use 64-bit floating point registers (MIPS only)">; +def mfp32 : Flag<["-"], "mfp32">, Group<m_Group>, + HelpText<"Use 32-bit floating point registers (MIPS only)">; +def mnan_EQ : Joined<["-"], "mnan=">, Group<m_Group>; +def mips32 : Flag<["-"], "mips32">, + Alias<march_EQ>, AliasArgs<["mips32"]>, HelpText<"Equivalent to -march=mips32">, Flags<[HelpHidden]>; -def mips32r2 : Flag<["-"], "mips32r2">, Group<mips_CPUs_Group>, +def mips32r2 : Flag<["-"], "mips32r2">, + Alias<march_EQ>, AliasArgs<["mips32r2"]>, HelpText<"Equivalent to -march=mips32r2">, Flags<[HelpHidden]>; -def mips64 : Flag<["-"], "mips64">, Group<mips_CPUs_Group>, +def mips64 : Flag<["-"], "mips64">, + Alias<march_EQ>, AliasArgs<["mips64"]>, HelpText<"Equivalent to -march=mips64">, Flags<[HelpHidden]>; -def mips64r2 : Flag<["-"], "mips64r2">, Group<mips_CPUs_Group>, +def mips64r2 : Flag<["-"], "mips64r2">, + Alias<march_EQ>, AliasArgs<["mips64r2"]>, HelpText<"Equivalent to -march=mips64r2">, Flags<[HelpHidden]>; def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>; def mthumb : Flag<["-"], "mthumb">, Group<m_Group>; @@ -991,8 +1159,6 @@ 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>; @@ -1006,6 +1172,7 @@ def nodefaultlibs : Flag<["-"], "nodefaultlibs">; def nofixprebinding : Flag<["-"], "nofixprebinding">; def nolibc : Flag<["-"], "nolibc">; def nomultidefs : Flag<["-"], "nomultidefs">; +def nopie : Flag<["-"], "nopie">; def noprebind : Flag<["-"], "noprebind">; def noseglinkedit : Flag<["-"], "noseglinkedit">; def nostartfiles : Flag<["-"], "nostartfiles">; @@ -1086,16 +1253,16 @@ 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 std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>, + Group<CompileOnly_Group>, HelpText<"Language standard to compile for">; 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 target : Joined<["--"], "target=">, Flags<[DriverOption]>, HelpText<"Generate code for the given target">; -def gcc_toolchain : Separate<["-"], "gcc-toolchain">, Flags<[DriverOption]>, +def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[DriverOption]>, HelpText<"Use the gcc toolchain at the given directory">; def time : Flag<["-"], "time">, HelpText<"Time individual commands">; @@ -1113,7 +1280,6 @@ 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]>, HelpText<"Show commands to run and use verbose output">; def verify : Flag<["-"], "verify">, Flags<[DriverOption,CC1Option]>, @@ -1138,6 +1304,7 @@ def working_directory_EQ : Joined<["-"], "working-directory=">, Flags<[CC1Option // Double dash options, which are usually an alias for one of the previous // options. +def _mhwdiv_EQ : Separate<["--"], "mhwdiv">, Alias<mhwdiv_EQ>; def _CLASSPATH_EQ : Joined<["--"], "CLASSPATH=">, Alias<fclasspath_EQ>; def _CLASSPATH : Separate<["--"], "CLASSPATH">, Alias<fclasspath_EQ>; def _all_warnings : Flag<["--"], "all-warnings">, Alias<Wall>; @@ -1162,6 +1329,8 @@ 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 _dyld_prefix_EQ : Joined<["--"], "dyld-prefix=">; +def _dyld_prefix : Separate<["--"], "dyld-prefix">, Alias<_dyld_prefix_EQ>; def _encoding_EQ : Joined<["--"], "encoding=">, Alias<fencoding_EQ>; def _encoding : Separate<["--"], "encoding">, Alias<fencoding_EQ>; def _entry : Flag<["--"], "entry">, Alias<e>; @@ -1192,10 +1361,6 @@ 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>; @@ -1243,6 +1408,22 @@ 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 mv1 : Flag<["-"], "mv1">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, + AliasArgs<["v1"]>; +def mv2 : Flag<["-"], "mv2">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, + AliasArgs<["v2"]>; +def mv3 : Flag<["-"], "mv3">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, + AliasArgs<["v3"]>; +def mv4 : Flag<["-"], "mv4">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, + AliasArgs<["v4"]>; +def mv5 : Flag<["-"], "mv5">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, + AliasArgs<["v5"]>; + +// These are legacy user-facing driver-level option spellings. They are always +// aliases for options that are spelled using the more common Unix / GNU flag +// style of double-dash and equals-joined flags. +def gcc_toolchain_legacy_spelling : Separate<["-"], "gcc-toolchain">, Alias<gcc_toolchain>; +def target_legacy_spelling : Separate<["-"], "target">, Alias<target>; // Special internal option to handle -Xlinker --no-demangle. def Z_Xlinker__no_demangle : Flag<["-"], "Z-Xlinker-no-demangle">, @@ -1258,4 +1439,140 @@ def Z_reserved_lib_stdcxx : Flag<["-"], "Z-reserved-lib-stdc++">, def Z_reserved_lib_cckext : Flag<["-"], "Z-reserved-lib-cckext">, Flags<[LinkerInput, NoArgumentUnused, Unsupported]>, Group<reserved_lib_Group>; +// Ignored options +// FIXME: multiclasess produce suffixes, not prefixes. This is fine for now +// since it is only used in ignored options. +multiclass BooleanFFlag<string name> { + def _f : Flag<["-"], "f"#name>; + def _fno : Flag<["-"], "fno-"#name>; +} + +def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_f_Group>; + +defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_f_Group>; +def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_f_Group>; +def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<clang_ignored_f_Group>; + +defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_f_Group>; +def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_f_Group>; + +// FIXME: This option should be supported and wired up to our diognostics, but +// ignore it for now to avoid breaking builds that use it. +def fdiagnostics_show_location_EQ : Joined<["-"], "fdiagnostics-show-location=">, Group<clang_ignored_f_Group>; + +defm eliminate_unused_debug_types : BooleanFFlag<"eliminate-unused-debug-types">, Group<clang_ignored_f_Group>; +defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_f_Group>; +defm function_attribute_list : BooleanFFlag<"function-attribute-list">, Group<clang_ignored_f_Group>; +defm gcse : BooleanFFlag<"gcse">, Group<clang_ignored_f_Group>; +defm gnu : BooleanFFlag<"gnu">, Group<clang_ignored_f_Group>; +defm ident : BooleanFFlag<"ident">, Group<clang_ignored_f_Group>; +defm implicit_templates : BooleanFFlag<"implicit-templates">, Group<clang_ignored_f_Group>; +defm inline_limit : BooleanFFlag<"inline-limit">, Group<clang_ignored_f_Group>; +defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_f_Group>; +defm non_call_exceptions : BooleanFFlag<"non-call-exceptions">, Group<clang_ignored_f_Group>; +defm permissive : BooleanFFlag<"permissive">, Group<clang_ignored_f_Group>; +defm prefetch_loop_arrays : BooleanFFlag<"prefetch-loop-arrays">, Group<clang_ignored_f_Group>; +defm printf : BooleanFFlag<"printf">, Group<clang_ignored_f_Group>; +defm profile : BooleanFFlag<"profile">, Group<clang_ignored_f_Group>; +defm profile_correction : BooleanFFlag<"profile-correction">, Group<clang_ignored_f_Group>; +defm profile_generate_sampling : BooleanFFlag<"profile-generate-sampling">, Group<clang_ignored_f_Group>; +defm profile_reusedist : BooleanFFlag<"profile-reusedist">, Group<clang_ignored_f_Group>; +defm profile_values : BooleanFFlag<"profile-values">, Group<clang_ignored_f_Group>; +defm regs_graph : BooleanFFlag<"regs-graph">, Group<clang_ignored_f_Group>; +defm ripa : BooleanFFlag<"ripa">, Group<clang_ignored_f_Group>; +defm rounding_math : BooleanFFlag<"rounding-math">, Group<clang_ignored_f_Group>; +defm schedule_insns : BooleanFFlag<"schedule-insns">, Group<clang_ignored_f_Group>; +defm see : BooleanFFlag<"see">, Group<clang_ignored_f_Group>; +defm signaling_nans : BooleanFFlag<"signaling-nans">, Group<clang_ignored_f_Group>; +defm spec_constr_count : BooleanFFlag<"spec-constr-count">, Group<clang_ignored_f_Group>; +defm strength_reduce : + BooleanFFlag<"strength-reduce">, Group<clang_ignored_f_Group>; +defm tls_model : BooleanFFlag<"tls-model">, Group<clang_ignored_f_Group>; +defm tracer : BooleanFFlag<"tracer">, Group<clang_ignored_f_Group>; +defm tree_salias : BooleanFFlag<"tree-salias">, Group<clang_ignored_f_Group>; +defm tree_vectorizer_verbose : BooleanFFlag<"tree-vectorizer-verbose">, Group<clang_ignored_f_Group>; +defm unroll_all_loops : BooleanFFlag<"unroll-all-loops">, Group<clang_ignored_f_Group>; +defm unswitch_loops : BooleanFFlag<"unswitch-loops">, Group<clang_ignored_f_Group>; + + +// gfortran options that we recognize in the driver and pass along when +// invoking GCC to compile Fortran code. +def gfortran_Group : OptionGroup<"gfortran Group">; + +// Generic gfortran options. +def A_DASH : Joined<["-"], "A-">, Group<gfortran_Group>; +def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined]>, Group<gfortran_Group>; +def cpp : Flag<["-"], "cpp">, Group<gfortran_Group>; +def nocpp : Flag<["-"], "nocpp">, Group<gfortran_Group>; +def static_libgfortran : Flag<["-"], "static-libgfortran">, Group<gfortran_Group>; + +// "f" options with values for gfortran. +def fblas_matmul_limit_EQ : Joined<["-"], "fblas-matmul-limit=">, Group<gfortran_Group>; +def fcheck_EQ : Joined<["-"], "fcheck=">, Group<gfortran_Group>; +def fcoarray_EQ : Joined<["-"], "fcoarray=">, Group<gfortran_Group>; +def fconvert_EQ : Joined<["-"], "fconvert=">, Group<gfortran_Group>; +def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<gfortran_Group>; +def ffpe_trap_EQ : Joined<["-"], "ffpe-trap=">, Group<gfortran_Group>; +def ffree_line_length_VALUE : Joined<["-"], "ffree-line-length-">, Group<gfortran_Group>; +def finit_character_EQ : Joined<["-"], "finit-character=">, Group<gfortran_Group>; +def finit_integer_EQ : Joined<["-"], "finit-integer=">, Group<gfortran_Group>; +def finit_logical_EQ : Joined<["-"], "finit-logical=">, Group<gfortran_Group>; +def finit_real_EQ : Joined<["-"], "finit-real=">, Group<gfortran_Group>; +def fmax_array_constructor_EQ : Joined<["-"], "fmax-array-constructor=">, Group<gfortran_Group>; +def fmax_errors_EQ : Joined<["-"], "fmax-errors=">, Group<gfortran_Group>; +def fmax_stack_var_size_EQ : Joined<["-"], "fmax-stack-var-size=">, Group<gfortran_Group>; +def fmax_subrecord_length_EQ : Joined<["-"], "fmax-subrecord-length=">, Group<gfortran_Group>; +def frecord_marker_EQ : Joined<["-"], "frecord-marker=">, Group<gfortran_Group>; + +// "f" flags for gfortran. +defm aggressive_function_elimination : BooleanFFlag<"aggressive-function-elimination">, Group<gfortran_Group>; +defm align_commons : BooleanFFlag<"align-commons">, Group<gfortran_Group>; +defm all_intrinsics : BooleanFFlag<"all-intrinsics">, Group<gfortran_Group>; +defm automatic : BooleanFFlag<"automatic">, Group<gfortran_Group>; +defm backslash : BooleanFFlag<"backslash">, Group<gfortran_Group>; +defm backtrace : BooleanFFlag<"backtrace">, Group<gfortran_Group>; +defm bounds_check : BooleanFFlag<"bounds-check">, Group<gfortran_Group>; +defm check_array_temporaries : BooleanFFlag<"check-array-temporaries">, Group<gfortran_Group>; +defm cray_pointer : BooleanFFlag<"cray-pointer">, Group<gfortran_Group>; +defm d_lines_as_code : BooleanFFlag<"d-lines-as-code">, Group<gfortran_Group>; +defm d_lines_as_comments : BooleanFFlag<"d-lines-as-comments">, Group<gfortran_Group>; +defm default_double_8 : BooleanFFlag<"default-double-8">, Group<gfortran_Group>; +defm default_integer_8 : BooleanFFlag<"default-integer-8">, Group<gfortran_Group>; +defm default_real_8 : BooleanFFlag<"default-real-8">, Group<gfortran_Group>; +defm dollar_ok : BooleanFFlag<"dollar-ok">, Group<gfortran_Group>; +defm dump_fortran_optimized : BooleanFFlag<"dump-fortran-optimized">, Group<gfortran_Group>; +defm dump_fortran_original : BooleanFFlag<"dump-fortran-original">, Group<gfortran_Group>; +defm dump_parse_tree : BooleanFFlag<"dump-parse-tree">, Group<gfortran_Group>; +defm external_blas : BooleanFFlag<"external-blas">, Group<gfortran_Group>; +defm f2c : BooleanFFlag<"f2c">, Group<gfortran_Group>; +defm fixed_form : BooleanFFlag<"fixed-form">, Group<gfortran_Group>; +defm free_form : BooleanFFlag<"free-form">, Group<gfortran_Group>; +defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group<gfortran_Group>; +defm implicit_none : BooleanFFlag<"implicit-none">, Group<gfortran_Group>; +defm init_local_zero : BooleanFFlag<"init-local-zero">, Group<gfortran_Group>; +defm integer_4_integer_8 : BooleanFFlag<"integer-4-integer-8">, Group<gfortran_Group>; +defm intrinsic_modules_path : BooleanFFlag<"intrinsic-modules-path">, Group<gfortran_Group>; +defm max_identifier_length : BooleanFFlag<"max-identifier-length">, Group<gfortran_Group>; +defm module_private : BooleanFFlag<"module-private">, Group<gfortran_Group>; +defm pack_derived : BooleanFFlag<"pack-derived">, Group<gfortran_Group>; +defm protect_parens : BooleanFFlag<"protect-parens">, Group<gfortran_Group>; +defm range_check : BooleanFFlag<"range-check">, Group<gfortran_Group>; +defm real_4_real_10 : BooleanFFlag<"real-4-real-10">, Group<gfortran_Group>; +defm real_4_real_16 : BooleanFFlag<"real-4-real-16">, Group<gfortran_Group>; +defm real_4_real_8 : BooleanFFlag<"real-4-real-8">, Group<gfortran_Group>; +defm real_8_real_10 : BooleanFFlag<"real-8-real-10">, Group<gfortran_Group>; +defm real_8_real_16 : BooleanFFlag<"real-8-real-16">, Group<gfortran_Group>; +defm real_8_real_4 : BooleanFFlag<"real-8-real-4">, Group<gfortran_Group>; +defm realloc_lhs : BooleanFFlag<"realloc-lhs">, Group<gfortran_Group>; +defm recursive : BooleanFFlag<"recursive">, Group<gfortran_Group>; +defm repack_arrays : BooleanFFlag<"repack-arrays">, Group<gfortran_Group>; +defm second_underscore : BooleanFFlag<"second-underscore">, Group<gfortran_Group>; +defm sign_zero : BooleanFFlag<"sign-zero">, Group<gfortran_Group>; +defm stack_arrays : BooleanFFlag<"stack-arrays">, Group<gfortran_Group>; +defm underscoring : BooleanFFlag<"underscoring">, Group<gfortran_Group>; +defm whole_file : BooleanFFlag<"whole-file">, Group<gfortran_Group>; + + include "CC1Options.td" + +include "CLCompatOptions.td" diff --git a/contrib/llvm/tools/clang/include/clang/Driver/SanitizerArgs.h b/contrib/llvm/tools/clang/include/clang/Driver/SanitizerArgs.h new file mode 100644 index 0000000..35b8f89 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Driver/SanitizerArgs.h @@ -0,0 +1,147 @@ +//===--- SanitizerArgs.h - Arguments for sanitizer tools -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_ +#define CLANG_LIB_DRIVER_SANITIZERARGS_H_ + +#include <string> + +#include "llvm/Option/Arg.h" +#include "llvm/Option/ArgList.h" + +namespace clang { +namespace driver { + +class Driver; +class ToolChain; + +class SanitizerArgs { + /// Assign ordinals to sanitizer flags. We'll use the ordinal values as + /// bit positions within \c Kind. + enum SanitizeOrdinal { +#define SANITIZER(NAME, ID) SO_##ID, +#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group, +#include "clang/Basic/Sanitizers.def" + SO_Count + }; + + /// Bugs to catch at runtime. + enum SanitizeKind { +#define SANITIZER(NAME, ID) ID = 1 << SO_##ID, +#define SANITIZER_GROUP(NAME, ID, ALIAS) \ + ID = ALIAS, ID##Group = 1 << SO_##ID##Group, +#include "clang/Basic/Sanitizers.def" + NeedsAsanRt = Address, + NeedsTsanRt = Thread, + NeedsMsanRt = Memory, + NeedsDfsanRt = DataFlow, + NeedsLeakDetection = Leak, + NeedsUbsanRt = Undefined | Integer, + NotAllowedWithTrap = Vptr, + HasZeroBaseShadow = Thread | Memory | DataFlow + }; + unsigned Kind; + + std::string BlacklistFile; + bool MsanTrackOrigins; + bool AsanZeroBaseShadow; + bool UbsanTrapOnError; + + public: + SanitizerArgs(); + /// Parses the sanitizer arguments from an argument list. + SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args); + + bool needsAsanRt() const { return Kind & NeedsAsanRt; } + bool needsTsanRt() const { return Kind & NeedsTsanRt; } + bool needsMsanRt() const { return Kind & NeedsMsanRt; } + bool needsLeakDetection() const { return Kind & NeedsLeakDetection; } + bool needsLsanRt() const { + return needsLeakDetection() && !needsAsanRt(); + } + bool needsUbsanRt() const { + return !UbsanTrapOnError && (Kind & NeedsUbsanRt); + } + bool needsDfsanRt() const { return Kind & NeedsDfsanRt; } + + bool sanitizesVptr() const { return Kind & Vptr; } + bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; } + bool hasZeroBaseShadow() const { + return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow; + } + void addArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; + + private: + void clear(); + + /// Parse a single value from a -fsanitize= or -fno-sanitize= value list. + /// Returns OR of members of the \c SanitizeKind enumeration, or \c 0 + /// if \p Value is not known. + static unsigned parse(const char *Value); + + /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any + /// invalid components. + static unsigned parse(const Driver &D, const llvm::opt::Arg *A, + bool DiagnoseErrors); + + /// Parse a single flag of the form -f[no]sanitize=, or + /// -f*-sanitizer. Sets the masks defining required change of Kind value. + /// Returns true if the flag was parsed successfully. + static bool parse(const Driver &D, const llvm::opt::ArgList &Args, + const llvm::opt::Arg *A, unsigned &Add, unsigned &Remove, + bool DiagnoseErrors); + + /// Produce an argument string from ArgList \p Args, which shows how it + /// provides a sanitizer kind in \p Mask. For example, the argument list + /// "-fsanitize=thread,vptr -faddress-sanitizer" with mask \c NeedsUbsanRt + /// would produce "-fsanitize=vptr". + static std::string lastArgumentForKind(const Driver &D, + const llvm::opt::ArgList &Args, + unsigned Kind); + + /// Produce an argument string from argument \p A, which shows how it provides + /// a value in \p Mask. For instance, the argument + /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce + /// "-fsanitize=alignment". + static std::string describeSanitizeArg(const llvm::opt::ArgList &Args, + const llvm::opt::Arg *A, + unsigned Mask); + + static bool getDefaultBlacklistForKind(const Driver &D, unsigned Kind, + std::string &BLPath); + + /// Return the smallest superset of sanitizer set \p Kinds such that each + /// member of each group whose flag is set in \p Kinds has its flag set in the + /// result. + static unsigned expandGroups(unsigned Kinds); + + /// Return the subset of \p Kinds supported by toolchain \p TC. If + /// \p DiagnoseErrors is true, produce an error diagnostic for each sanitizer + /// removed from \p Kinds. + static unsigned filterUnsupportedKinds(const ToolChain &TC, unsigned Kinds, + const llvm::opt::ArgList &Args, + const llvm::opt::Arg *A, + bool DiagnoseErrors, + unsigned &DiagnosedKinds); + + /// The flags in \p Mask are unsupported by \p TC. If present in \p Kinds, + /// remove them and produce an error diagnostic referring to \p A if + /// \p DiagnoseErrors is true. + static void filterUnsupportedMask(const ToolChain &TC, unsigned &Kinds, + unsigned Mask, + const llvm::opt::ArgList &Args, + const llvm::opt::Arg *A, + bool DiagnoseErrors, + unsigned &DiagnosedKinds); +}; + +} // namespace driver +} // namespace clang + +#endif // CLANG_LIB_DRIVER_SANITIZERARGS_H_ diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Tool.h b/contrib/llvm/tools/clang/include/clang/Driver/Tool.h index 4c05d0a..015dcf5 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Tool.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Tool.h @@ -12,9 +12,15 @@ #include "clang/Basic/LLVM.h" +namespace llvm { +namespace opt { + class ArgList; +} +} + namespace clang { namespace driver { - class ArgList; + class Compilation; class InputInfo; class Job; @@ -57,7 +63,8 @@ public: virtual bool hasGoodDiagnostics() const { return false; } /// ConstructJob - Construct jobs to perform the action \p JA, - /// writing to \p Output and with \p Inputs. + /// writing to \p Output and with \p Inputs, and add the jobs to + /// \p C. /// /// \param TCArgs - The argument list for this toolchain, with any /// tool chain specific translations applied. @@ -66,7 +73,7 @@ public: virtual void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, - const ArgList &TCArgs, + const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const = 0; }; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h index aae3d79..84e0b55 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h @@ -19,16 +19,22 @@ #include "llvm/Support/Path.h" #include <string> +namespace llvm { +namespace opt { + class ArgList; + class DerivedArgList; + class InputArgList; +} +} + namespace clang { class ObjCRuntime; namespace driver { - class ArgList; class Compilation; - class DerivedArgList; class Driver; - class InputArgList; class JobAction; + class SanitizerArgs; class Tool; /// ToolChain - Access to tools for a single platform. @@ -49,7 +55,7 @@ public: private: const Driver &D; const llvm::Triple Triple; - const ArgList &Args; + const llvm::opt::ArgList &Args; /// The list of toolchain specific path prefixes to search for /// files. @@ -67,8 +73,11 @@ private: Tool *getLink() const; Tool *getClangAs() const; + mutable OwningPtr<SanitizerArgs> SanitizerArguments; + protected: - ToolChain(const Driver &D, const llvm::Triple &T, const ArgList &Args); + ToolChain(const Driver &D, const llvm::Triple &T, + const llvm::opt::ArgList &Args); virtual Tool *buildAssembler() const; virtual Tool *buildLinker() const; @@ -76,17 +85,18 @@ protected: /// \name Utilities for implementing subclasses. ///@{ - static void addSystemInclude(const ArgList &DriverArgs, - ArgStringList &CC1Args, + static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, const Twine &Path); - static void addExternCSystemInclude(const ArgList &DriverArgs, - ArgStringList &CC1Args, + static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, + const Twine &Path); + static void + addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, const Twine &Path); - static void addExternCSystemIncludeIfExists(const ArgList &DriverArgs, - ArgStringList &CC1Args, - const Twine &Path); - static void addSystemIncludes(const ArgList &DriverArgs, - ArgStringList &CC1Args, + static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, ArrayRef<StringRef> Paths); ///@} @@ -117,6 +127,8 @@ public: path_list &getProgramPaths() { return ProgramPaths; } const path_list &getProgramPaths() const { return ProgramPaths; } + const SanitizerArgs& getSanitizerArgs() const; + // Tool access. /// TranslateArgs - Create a new derived argument list for any argument @@ -124,8 +136,9 @@ public: /// specific translations are needed. /// /// \param BoundArch - The bound architecture name, or 0. - virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args, - const char *BoundArch) const { + virtual llvm::opt::DerivedArgList * + TranslateArgs(const llvm::opt::DerivedArgList &Args, + const char *BoundArch) const { return 0; } @@ -137,6 +150,13 @@ public: std::string GetFilePath(const char *Name) const; std::string GetProgramPath(const char *Name) const; + /// \brief Dispatch to the specific toolchain for verbose printing. + /// + /// This is used when handling the verbose option to print detailed, + /// toolchain-specific information useful for understanding the behavior of + /// the driver on a specific platform. + virtual void printVerboseInfo(raw_ostream &OS) const {}; + // Platform defaults information /// HasNativeLTOLinker - Check whether the linker and related tools have @@ -157,17 +177,9 @@ public: /// \brief Check if the toolchain should use the integrated assembler. bool useIntegratedAs() const; - /// IsStrictAliasingDefault - Does this tool chain use -fstrict-aliasing by - /// default. - virtual bool IsStrictAliasingDefault() const { return true; } - /// IsMathErrnoDefault - Does this tool chain use -fmath-errno by default. virtual bool IsMathErrnoDefault() const { return true; } - /// IsObjCDefaultSynthPropertiesDefault - Does this tool chain enable - /// -fobjc-default-synthesize-properties by default. - virtual bool IsObjCDefaultSynthPropertiesDefault() const { return true; } - /// IsEncodeExtendedBlockSignatureDefault - Does this tool chain enable /// -fencode-extended-block-signature by default. virtual bool IsEncodeExtendedBlockSignatureDefault() const { return false; } @@ -225,16 +237,18 @@ public: /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking /// command line arguments into account. - virtual std::string ComputeLLVMTriple(const ArgList &Args, - types::ID InputType = types::TY_INVALID) const; + virtual std::string + ComputeLLVMTriple(const llvm::opt::ArgList &Args, + types::ID InputType = types::TY_INVALID) const; /// ComputeEffectiveClangTriple - Return the Clang triple to use for this /// target, which may take into account the command line arguments. For /// example, on Darwin the -mmacosx-version-min= command line argument (which /// sets the deployment target) determines the version in the triple passed to /// Clang. - virtual std::string ComputeEffectiveClangTriple(const ArgList &Args, - types::ID InputType = types::TY_INVALID) const; + virtual std::string ComputeEffectiveClangTriple( + const llvm::opt::ArgList &Args, + types::ID InputType = types::TY_INVALID) const; /// getDefaultObjCRuntime - Return the default Objective-C runtime /// for this platform. @@ -253,42 +267,46 @@ public: /// /// This routine is responsible for adding the necessary cc1 arguments to /// include headers from standard system header directories. - virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs, - ArgStringList &CC1Args) const; + virtual void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; /// \brief Add options that need to be passed to cc1 for this target. - virtual void addClangTargetOptions(const ArgList &DriverArgs, - ArgStringList &CC1Args) const; + virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; // GetRuntimeLibType - Determine the runtime library type to use with the // given compilation arguments. - virtual RuntimeLibType GetRuntimeLibType(const ArgList &Args) const; + virtual RuntimeLibType + GetRuntimeLibType(const llvm::opt::ArgList &Args) const; // GetCXXStdlibType - Determine the C++ standard library type to use with the // given compilation arguments. - virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const; + virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const; /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set /// the include paths to use for the given C++ standard library type. - virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, - ArgStringList &CC1Args) const; + virtual void + AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; /// AddCXXStdlibLibArgs - Add the system specific linker arguments to use /// for the given C++ standard library type. - virtual void AddCXXStdlibLibArgs(const ArgList &Args, - ArgStringList &CmdArgs) const; + virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; /// AddCCKextLibArgs - Add the system specific linker arguments to use /// for kernel extensions (Darwin-specific). - virtual void AddCCKextLibArgs(const ArgList &Args, - ArgStringList &CmdArgs) const; + virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::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; + virtual bool + AddFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; }; } // end namespace driver diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Types.def b/contrib/llvm/tools/clang/include/clang/Driver/Types.def index 42f0709..d4f52d3 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Types.def +++ b/contrib/llvm/tools/clang/include/clang/Driver/Types.def @@ -66,7 +66,7 @@ TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, 0, "pu") // Other languages. TYPE("ada", Ada, INVALID, 0, "u") TYPE("assembler", PP_Asm, INVALID, "s", "au") -TYPE("assembler-with-cpp", Asm, PP_Asm, 0, "au") +TYPE("assembler-with-cpp", Asm, PP_Asm, "S", "au") TYPE("f95", PP_Fortran, INVALID, 0, "u") TYPE("f95-cpp-input", Fortran, PP_Fortran, 0, "u") TYPE("java", Java, INVALID, 0, "u") diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Types.h b/contrib/llvm/tools/clang/include/clang/Driver/Types.h index 18cd2d5..cca576a 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Types.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Types.h @@ -34,7 +34,7 @@ namespace types { /// getTypeTempSuffix - Return the suffix to use when creating a /// temp file of this type, or null if unspecified. - const char *getTypeTempSuffix(ID Id); + const char *getTypeTempSuffix(ID Id, bool CLMode = false); /// onlyAssembleType - Should this type only be assembled. bool onlyAssembleType(ID Id); @@ -78,7 +78,7 @@ namespace types { /// done for type 'Id'. void getCompilationPhases( ID Id, - llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &Phases); + llvm::SmallVectorImpl<phases::ID> &Phases); /// lookupCXXTypeForCType - Lookup CXX input type that corresponds to given /// C type (used for clang++ emulation of g++ behaviour) diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Util.h b/contrib/llvm/tools/clang/include/clang/Driver/Util.h index 06b82b9..b24b990 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Util.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Util.h @@ -14,13 +14,12 @@ #include "llvm/ADT/DenseMap.h" namespace clang { +class DiagnosticsEngine; + namespace driver { class Action; class JobAction; - /// ArgStringList - Type used for constructing argv lists for subprocesses. - typedef SmallVector<const char*, 16> ArgStringList; - /// ArgStringMap - Type used to map a JobAction to its result file. typedef llvm::DenseMap<const JobAction*, const char*> ArgStringMap; diff --git a/contrib/llvm/tools/clang/include/clang/Edit/Commit.h b/contrib/llvm/tools/clang/include/clang/Edit/Commit.h index 48e3d59..626b1dd 100644 --- a/contrib/llvm/tools/clang/include/clang/Edit/Commit.h +++ b/contrib/llvm/tools/clang/include/clang/Edit/Commit.h @@ -13,6 +13,7 @@ #include "clang/Edit/FileOffset.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" namespace clang { class LangOptions; @@ -48,16 +49,19 @@ private: const LangOptions &LangOpts; const PPConditionalDirectiveRecord *PPRec; EditedSource *Editor; - + + const bool ForceCommitInSystemHeader; bool IsCommitable; SmallVector<Edit, 8> CachedEdits; + + llvm::BumpPtrAllocator StrAlloc; public: explicit Commit(EditedSource &Editor); Commit(const SourceManager &SM, const LangOptions &LangOpts, const PPConditionalDirectiveRecord *PPRec = 0) : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0), - IsCommitable(true) { } + ForceCommitInSystemHeader(true), IsCommitable(true) { } bool isCommitable() const { return IsCommitable; } @@ -103,7 +107,7 @@ public: CharSourceRange::getTokenRange(TokenInnerRange)); } - typedef SmallVector<Edit, 8>::const_iterator edit_iterator; + typedef SmallVectorImpl<Edit>::const_iterator edit_iterator; edit_iterator edit_begin() const { return CachedEdits.begin(); } edit_iterator edit_end() const { return CachedEdits.end(); } @@ -131,6 +135,12 @@ private: SourceLocation *MacroBegin = 0) const; bool isAtEndOfMacroExpansion(SourceLocation loc, SourceLocation *MacroEnd = 0) const; + + StringRef copyString(StringRef str) { + char *buf = StrAlloc.Allocate<char>(str.size()); + std::memcpy(buf, str.data(), str.size()); + return StringRef(buf, str.size()); + } }; } diff --git a/contrib/llvm/tools/clang/include/clang/Edit/EditedSource.h b/contrib/llvm/tools/clang/include/clang/Edit/EditedSource.h index 733ad40..3ad5a6b 100644 --- a/contrib/llvm/tools/clang/include/clang/Edit/EditedSource.h +++ b/contrib/llvm/tools/clang/include/clang/Edit/EditedSource.h @@ -28,6 +28,7 @@ class EditedSource { const SourceManager &SourceMgr; const LangOptions &LangOpts; const PPConditionalDirectiveRecord *PPRec; + const bool ForceCommitInSystemHeader; struct FileEdit { StringRef Text; @@ -45,8 +46,10 @@ class EditedSource { public: EditedSource(const SourceManager &SM, const LangOptions &LangOpts, - const PPConditionalDirectiveRecord *PPRec = 0) + const PPConditionalDirectiveRecord *PPRec = 0, + const bool FCommitInSystemHeader = true) : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), + ForceCommitInSystemHeader(FCommitInSystemHeader), StrAlloc(/*size=*/512) { } const SourceManager &getSourceManager() const { return SourceMgr; } @@ -54,6 +57,10 @@ public: const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const { return PPRec; } + + bool getForceCommitInSystemHeader() const { + return ForceCommitInSystemHeader; + } bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs); diff --git a/contrib/llvm/tools/clang/include/clang/Edit/Rewriters.h b/contrib/llvm/tools/clang/include/clang/Edit/Rewriters.h index 292878e..5e3425f 100644 --- a/contrib/llvm/tools/clang/include/clang/Edit/Rewriters.h +++ b/contrib/llvm/tools/clang/include/clang/Edit/Rewriters.h @@ -9,10 +9,16 @@ #ifndef LLVM_CLANG_EDIT_REWRITERS_H #define LLVM_CLANG_EDIT_REWRITERS_H +#include "llvm/ADT/SmallVector.h" namespace clang { class ObjCMessageExpr; + class ObjCMethodDecl; + class ObjCInterfaceDecl; + class ObjCProtocolDecl; class NSAPI; + class EnumDecl; + class TypedefDecl; class ParentMap; namespace edit { @@ -24,7 +30,7 @@ bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg, bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit, const ParentMap *PMap); - + bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit); diff --git a/contrib/llvm/tools/clang/include/clang/Format/Format.h b/contrib/llvm/tools/clang/include/clang/Format/Format.h index 5304dc7..0f27467 100644 --- a/contrib/llvm/tools/clang/include/clang/Format/Format.h +++ b/contrib/llvm/tools/clang/include/clang/Format/Format.h @@ -17,6 +17,7 @@ #include "clang/Frontend/FrontendAction.h" #include "clang/Tooling/Refactoring.h" +#include "llvm/Support/system_error.h" namespace clang { @@ -30,13 +31,29 @@ namespace format { /// specific guidelines. struct FormatStyle { /// \brief The column limit. + /// + /// A column limit of \c 0 means that there is no column limit. In this case, + /// clang-format will respect the input's line breaking decisions within + /// statements. unsigned ColumnLimit; + /// \brief The maximum number of consecutive empty lines to keep. + unsigned MaxEmptyLinesToKeep; + + /// \brief The penalty for each line break introduced inside a comment. + unsigned PenaltyBreakComment; + + /// \brief The penalty for each line break introduced inside a string literal. + unsigned PenaltyBreakString; + /// \brief The penalty for each character outside of the column limit. unsigned PenaltyExcessCharacter; - /// \brief The maximum number of consecutive empty lines to keep. - unsigned MaxEmptyLinesToKeep; + /// \brief The penalty for breaking before the first \c <<. + unsigned PenaltyBreakFirstLessLess; + + /// \brief The penalty for breaking a function call after "call(". + unsigned PenaltyBreakBeforeFirstCallParameter; /// \brief Set whether & and * bind to the type as opposed to the variable. bool PointerBindsToType; @@ -44,32 +61,62 @@ struct FormatStyle { /// \brief If \c true, analyze the formatted file for the most common binding. bool DerivePointerBinding; - /// \brief The extra indent or outdent of access modifiers (e.g.: public:). + /// \brief The extra indent or outdent of access modifiers, e.g. \c public:. int AccessModifierOffset; + /// \brief Supported language standards. enum LanguageStandard { + /// Use C++03-compatible syntax. LS_Cpp03, + /// Use features of C++11 (e.g. \c A<A<int>> instead of + /// <tt>A<A<int> ></tt>). LS_Cpp11, + /// Automatic detection based on the input. LS_Auto }; - /// \brief Format compatible with this standard, e.g. use \c A<A<int> > - /// instead of \c A<A<int>> for LS_Cpp03. + /// \brief Format compatible with this standard, e.g. use + /// <tt>A<A<int> ></tt> instead of \c A<A<int>> for LS_Cpp03. LanguageStandard Standard; /// \brief Indent case labels one level from the switch statement. /// - /// When false, use the same indentation level as for the switch statement. + /// When \c false, use the same indentation level as for the switch statement. /// Switch statement body is always indented one level more than case labels. bool IndentCaseLabels; + /// \brief Different ways to indent namespace contents. + enum NamespaceIndentationKind { + /// Don't indent in namespaces. + NI_None, + /// Indent only in inner namespaces (nested in other namespaces). + NI_Inner, + /// Indent in all namespaces. + NI_All + }; + + /// \brief The indentation used for namespaces. + NamespaceIndentationKind NamespaceIndentation; + /// \brief The number of spaces to before trailing line comments. unsigned SpacesBeforeTrailingComments; - /// \brief If false, a function call's or function definition's parameters + /// \brief If \c false, a function call's or function definition's parameters /// will either all be on the same line or will have one line each. bool BinPackParameters; + /// \brief If \c true, clang-format detects whether function calls and + /// definitions are formatted with one parameter per line. + /// + /// Each call can be bin-packed, one-per-line or inconclusive. If it is + /// inconclusive, e.g. completely on one line, but a decision needs to be + /// made, clang-format analyzes whether there are other bin-packed cases in + /// the input file and act accordingly. + /// + /// NOTE: This is an experimental flag, that might go away or be renamed. Do + /// not use this in config files, etc. Use at your own risk. + bool ExperimentalAutoDetectBinPacking; + /// \brief Allow putting all parameters of a function declaration onto /// the next line even if \c BinPackParameters is \c false. bool AllowAllParametersOfDeclarationOnNextLine; @@ -82,16 +129,176 @@ struct FormatStyle { /// initializer on its own line. bool ConstructorInitializerAllOnOneLineOrOnePerLine; - /// \brief If true, "if (a) return;" can be put on a single line. + /// \brief Always break constructor initializers before commas and align + /// the commas with the colon. + bool BreakConstructorInitializersBeforeComma; + + /// \brief If \c true, <tt>if (a) return;</tt> can be put on a single + /// line. bool AllowShortIfStatementsOnASingleLine; + /// \brief If \c true, <tt>while (true) continue;</tt> can be put on a + /// single line. + bool AllowShortLoopsOnASingleLine; + /// \brief Add a space in front of an Objective-C protocol list, i.e. use - /// Foo <Protocol> instead of Foo<Protocol>. + /// <tt>Foo <Protocol></tt> instead of \c Foo<Protocol>. bool ObjCSpaceBeforeProtocolList; + /// \brief If \c true, aligns trailing comments. + bool AlignTrailingComments; + /// \brief If \c true, aligns escaped newlines as far left as possible. /// Otherwise puts them into the right-most column. bool AlignEscapedNewlinesLeft; + + /// \brief The number of columns to use for indentation. + unsigned IndentWidth; + + /// \brief The number of columns used for tab stops. + unsigned TabWidth; + + /// \brief The number of characters to use for indentation of constructor + /// initializer lists. + unsigned ConstructorInitializerIndentWidth; + + /// \brief If \c true, always break after the <tt>template<...></tt> of a + /// template declaration. + bool AlwaysBreakTemplateDeclarations; + + /// \brief If \c true, always break before multiline string literals. + bool AlwaysBreakBeforeMultilineStrings; + + /// \brief Different ways to use tab in formatting. + enum UseTabStyle { + /// Never use tab. + UT_Never, + /// Use tabs only for indentation. + UT_ForIndentation, + /// Use tabs whenever we need to fill whitespace that spans at least from + /// one tab stop to the next one. + UT_Always + }; + + /// \brief The way to use tab characters in the resulting file. + UseTabStyle UseTab; + + /// \brief If \c true, binary operators will be placed after line breaks. + bool BreakBeforeBinaryOperators; + + /// \brief If \c true, ternary operators will be placed after line breaks. + bool BreakBeforeTernaryOperators; + + /// \brief Different ways to attach braces to their surrounding context. + enum BraceBreakingStyle { + /// Always attach braces to surrounding context. + BS_Attach, + /// Like \c Attach, but break before braces on function, namespace and + /// class definitions. + BS_Linux, + /// Like \c Attach, but break before function definitions. + BS_Stroustrup, + /// Always break before braces. + BS_Allman + }; + + /// \brief The brace breaking style to use. + BraceBreakingStyle BreakBeforeBraces; + + /// \brief If \c true, format braced lists as best suited for C++11 braced + /// lists. + /// + /// Important differences: + /// - No spaces inside the braced list. + /// - No line break before the closing brace. + /// - Indentation with the continuation indent, not with the block indent. + /// + /// Fundamentally, C++11 braced lists are formatted exactly like function + /// calls would be formatted in their place. If the braced list follows a name + /// (e.g. a type or variable name), clang-format formats as if the \c {} were + /// the parentheses of a function call with that name. If there is no name, + /// a zero-length name is assumed. + bool Cpp11BracedListStyle; + + /// \brief If \c true, indent when breaking function declarations which + /// are not also definitions after the type. + bool IndentFunctionDeclarationAfterType; + + /// \brief If \c true, spaces will be inserted after '(' and before ')'. + bool SpacesInParentheses; + + /// \brief If \c true, spaces will be inserted after '<' and before '>' in + /// template argument lists + bool SpacesInAngles; + + /// \brief If \c false, spaces may be inserted into '()'. + bool SpaceInEmptyParentheses; + + /// \brief If \c false, spaces may be inserted into C style casts. + bool SpacesInCStyleCastParentheses; + + /// \brief If \c true, spaces will be inserted between 'for'/'if'/'while'/... + /// and '('. + bool SpaceAfterControlStatementKeyword; + + /// \brief If \c false, spaces will be removed before assignment operators. + bool SpaceBeforeAssignmentOperators; + + /// \brief Indent width for line continuations. + unsigned ContinuationIndentWidth; + + bool operator==(const FormatStyle &R) const { + return AccessModifierOffset == R.AccessModifierOffset && + ConstructorInitializerIndentWidth == + R.ConstructorInitializerIndentWidth && + AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft && + AlignTrailingComments == R.AlignTrailingComments && + AllowAllParametersOfDeclarationOnNextLine == + R.AllowAllParametersOfDeclarationOnNextLine && + AllowShortIfStatementsOnASingleLine == + R.AllowShortIfStatementsOnASingleLine && + AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine && + AlwaysBreakTemplateDeclarations == + R.AlwaysBreakTemplateDeclarations && + AlwaysBreakBeforeMultilineStrings == + R.AlwaysBreakBeforeMultilineStrings && + BinPackParameters == R.BinPackParameters && + BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators && + BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && + BreakBeforeBraces == R.BreakBeforeBraces && + BreakConstructorInitializersBeforeComma == + R.BreakConstructorInitializersBeforeComma && + ColumnLimit == R.ColumnLimit && + ConstructorInitializerAllOnOneLineOrOnePerLine == + R.ConstructorInitializerAllOnOneLineOrOnePerLine && + DerivePointerBinding == R.DerivePointerBinding && + ExperimentalAutoDetectBinPacking == + R.ExperimentalAutoDetectBinPacking && + IndentCaseLabels == R.IndentCaseLabels && + IndentFunctionDeclarationAfterType == + R.IndentFunctionDeclarationAfterType && + IndentWidth == R.IndentWidth && + MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep && + NamespaceIndentation == R.NamespaceIndentation && + ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList && + PenaltyBreakComment == R.PenaltyBreakComment && + PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess && + PenaltyBreakString == R.PenaltyBreakString && + PenaltyExcessCharacter == R.PenaltyExcessCharacter && + PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine && + PointerBindsToType == R.PointerBindsToType && + SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments && + Cpp11BracedListStyle == R.Cpp11BracedListStyle && + Standard == R.Standard && TabWidth == R.TabWidth && + UseTab == R.UseTab && SpacesInParentheses == R.SpacesInParentheses && + SpacesInAngles == R.SpacesInAngles && + SpaceInEmptyParentheses == R.SpaceInEmptyParentheses && + SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses && + SpaceAfterControlStatementKeyword == + R.SpaceAfterControlStatementKeyword && + SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators && + ContinuationIndentWidth == R.ContinuationIndentWidth; + } }; /// \brief Returns a format style complying with the LLVM coding standards: @@ -110,6 +317,24 @@ FormatStyle getChromiumStyle(); /// https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style. FormatStyle getMozillaStyle(); +/// \brief Returns a format style complying with Webkit's style guide: +/// http://www.webkit.org/coding/coding-style.html +FormatStyle getWebKitStyle(); + +/// \brief Gets a predefined style by name. +/// +/// Currently supported names: LLVM, Google, Chromium, Mozilla. Names are +/// compared case-insensitively. +/// +/// Returns \c true if the Style has been set. +bool getPredefinedStyle(StringRef Name, FormatStyle *Style); + +/// \brief Parse configuration from YAML-formatted text. +llvm::error_code parseConfiguration(StringRef Text, FormatStyle *Style); + +/// \brief Gets configuration in a YAML string. +std::string configurationAsText(const FormatStyle &Style); + /// \brief Reformats the given \p Ranges in the token stream coming out of /// \c Lex. /// @@ -117,18 +342,49 @@ FormatStyle getMozillaStyle(); /// everything that might influence its formatting or might be influenced by its /// formatting. /// -/// \param DiagClient A custom DiagnosticConsumer. Can be 0, in this case -/// diagnostic is output to llvm::errs(). -/// /// Returns the \c Replacements necessary to make all \p Ranges comply with /// \p Style. tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex, SourceManager &SourceMgr, - std::vector<CharSourceRange> Ranges, - DiagnosticConsumer *DiagClient = 0); + std::vector<CharSourceRange> Ranges); + +/// \brief Reformats the given \p Ranges in \p Code. +/// +/// Otherwise identical to the reformat() function consuming a \c Lexer. +tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, + std::vector<tooling::Range> Ranges, + StringRef FileName = "<stdin>"); /// \brief Returns the \c LangOpts that the formatter expects you to set. -LangOptions getFormattingLangOpts(); +/// +/// \param Standard determines lexing mode: LC_Cpp11 and LS_Auto turn on C++11 +/// lexing mode, LS_Cpp03 - C++03 mode. +LangOptions getFormattingLangOpts(FormatStyle::LanguageStandard Standard = + FormatStyle::LS_Cpp11); + +/// \brief Description to be used for help text for a llvm::cl option for +/// specifying format style. The description is closely related to the operation +/// of getStyle(). +extern const char *StyleOptionHelpDescription; + +/// \brief Construct a FormatStyle based on \c StyleName. +/// +/// \c StyleName can take several forms: +/// \li "{<key>: <value>, ...}" - Set specic style parameters. +/// \li "<style name>" - One of the style names supported by +/// getPredefinedStyle(). +/// \li "file" - Load style configuration from a file called '.clang-format' +/// located in one of the parent directories of \c FileName or the current +/// directory if \c FileName is empty. +/// +/// \param[in] StyleName Style name to interpret according to the description +/// above. +/// \param[in] FileName Path to start search for .clang-format if \c StyleName +/// == "file". +/// +/// \returns FormatStyle as specified by \c StyleName. If no style could be +/// determined, the default is LLVM Style (see getLLVMStyle()). +FormatStyle getStyle(StringRef StyleName, StringRef FileName); } // end namespace format } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h index 3731478..366c499 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h @@ -16,9 +16,6 @@ #include "clang/Basic/LLVM.h" -namespace llvm { - namespace sys { class Path; } -} namespace clang { class ASTConsumer; @@ -37,16 +34,12 @@ ASTConsumer *CreateASTPrinter(raw_ostream *OS, StringRef FilterString); // AST dumper: dumps the raw AST in human-readable form to stderr; this is // intended for debugging. -ASTConsumer *CreateASTDumper(StringRef FilterString); +ASTConsumer *CreateASTDumper(StringRef FilterString, bool DumpLookups = false); // AST Decl node lister: prints qualified names of all filterable AST Decl // nodes. ASTConsumer *CreateASTDeclNodeLister(); -// AST XML-dumper: dumps out the AST to stderr in a very detailed XML -// format; this is intended for particularly intense debugging. -ASTConsumer *CreateASTDumperXML(raw_ostream &OS); - // Graphical AST viewer: for each function definition, creates a graph of // the AST and displays it with the graph viewer "dotty". Also outputs // function declarations to stderr. diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h index 02c57d7..43d77f0 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h @@ -25,7 +25,6 @@ #include "clang/Lex/ModuleLoader.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Sema/CodeCompleteConsumer.h" -#include "clang/Sema/Sema.h" #include "clang/Serialization/ASTBitCodes.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/OwningPtr.h" @@ -44,6 +43,7 @@ namespace llvm { } namespace clang { +class Sema; class ASTContext; class ASTReader; class CodeCompleteConsumer; @@ -75,6 +75,7 @@ private: IntrusiveRefCntPtr<TargetOptions> TargetOpts; IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts; ASTReader *Reader; + bool HadModuleLoaderFatalFailure; struct ASTWriterData; OwningPtr<ASTWriterData> WriterData; @@ -456,7 +457,7 @@ public: void setASTContext(ASTContext *ctx) { Ctx = ctx; } void setPreprocessor(Preprocessor *pp); - bool hasSema() const { return TheSema; } + bool hasSema() const { return TheSema.isValid(); } Sema &getSema() const { assert(TheSema && "ASTUnit does not have a Sema object!"); return *TheSema; @@ -471,13 +472,14 @@ public: return OriginalSourceFile; } + ASTMutationListener *getASTMutationListener(); ASTDeserializationListener *getDeserializationListener(); /// \brief Add a temporary file that the ASTUnit depends on. /// /// This file will be erased when the ASTUnit is destroyed. - void addTemporaryFile(const llvm::sys::Path &TempFile); - + void addTemporaryFile(StringRef TempFile); + bool getOnlyLocalDecls() const { return OnlyLocalDecls; } bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; } @@ -697,10 +699,10 @@ public: /// lifetime is expected to extend past that of the returned ASTUnit. /// /// \param Action - The ASTFrontendAction to invoke. Its ownership is not - /// transfered. + /// transferred. /// /// \param Unit - optionally an already created ASTUnit. Its ownership is not - /// transfered. + /// transferred. /// /// \param Persistent - if true the returned ASTUnit will be complete. /// false means the caller is only interested in getting info through the diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def index f6e2472..78b825d 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def @@ -39,11 +39,12 @@ 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(DisableFree , 1, 0) ///< Don't free memory. +CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing. 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(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing. 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 @@ -85,6 +86,10 @@ CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer ///< 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. + + /// If -fpcc-struct-return or -freg-struct-return is specified. +ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default) + CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. @@ -102,8 +107,12 @@ 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(RerollLoops , 1, 0) ///< Control whether loops are rerolled. CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns. CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables. +CODEGENOPT(VectorizeBB , 1, 0) ///< Run basic block vectorizer. +CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer. +CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer. /// Attempt to use register sized accesses to bit-fields in structures, when /// possible. @@ -131,6 +140,9 @@ VALUE_CODEGENOPT(SSPBufferSize, 32, 0) /// The kind of generated debug info. ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 2, NoDebugInfo) +/// Dwarf version. +VALUE_CODEGENOPT(DwarfVersion, 3, 0) + /// The kind of inlining to perform. ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining) diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h index db6b418..86aabf7 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h @@ -71,6 +71,12 @@ public: FPC_Fast // Aggressively fuse FP ops (E.g. FMA). }; + enum StructReturnConventionKind { + SRCK_Default, // No special option was passed. + SRCK_OnStack, // Small structs on the stack (-fpcc-struct-return). + SRCK_InRegs // Small structs in registers (-freg-struct-return). + }; + /// The code model to use (-mcmodel). std::string CodeModel; @@ -122,6 +128,12 @@ public: /// A list of command-line options to forward to the LLVM backend. std::vector<std::string> BackendOptions; + /// A list of dependent libraries. + std::vector<std::string> DependentLibraries; + + /// Name of the profile file to use with -fprofile-sample-use. + std::string SampleProfileFile; + public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h index dbd7606..5673c59 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h @@ -395,7 +395,7 @@ public: /// @name ASTConsumer /// { - bool hasASTConsumer() const { return Consumer != 0; } + bool hasASTConsumer() const { return Consumer.isValid(); } ASTConsumer &getASTConsumer() const { assert(Consumer && "Compiler instance has no AST consumer!"); @@ -413,7 +413,7 @@ public: /// } /// @name Semantic analysis /// { - bool hasSema() const { return TheSema != 0; } + bool hasSema() const { return TheSema.isValid(); } Sema &getSema() const { assert(TheSema && "Compiler instance has no Sema object!"); @@ -433,7 +433,9 @@ public: /// @name Code Completion /// { - bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; } + bool hasCodeCompletionConsumer() const { + return CompletionConsumer.isValid(); + } CodeCompleteConsumer &getCodeCompletionConsumer() const { assert(CompletionConsumer && @@ -455,7 +457,7 @@ public: /// @name Frontend timer /// { - bool hasFrontendTimer() const { return FrontendTimer != 0; } + bool hasFrontendTimer() const { return FrontendTimer.isValid(); } llvm::Timer &getFrontendTimer() const { assert(FrontendTimer && "Compiler instance has no frontend timer!"); @@ -589,10 +591,10 @@ public: /// \return - Null on error. llvm::raw_fd_ostream * createOutputFile(StringRef OutputPath, - bool Binary = true, bool RemoveFileOnSignal = true, - StringRef BaseInput = "", - StringRef Extension = "", - bool UseTemporary = false, + bool Binary, bool RemoveFileOnSignal, + StringRef BaseInput, + StringRef Extension, + bool UseTemporary, bool CreateMissingDirectories = false); /// Create a new output file, optionally deriving the output path name. @@ -622,13 +624,13 @@ public: /// will be stored here on success. static llvm::raw_fd_ostream * createOutputFile(StringRef OutputPath, std::string &Error, - bool Binary = true, bool RemoveFileOnSignal = true, - StringRef BaseInput = "", - StringRef Extension = "", - bool UseTemporary = false, - bool CreateMissingDirectories = false, - std::string *ResultPathName = 0, - std::string *TempPathName = 0); + bool Binary, bool RemoveFileOnSignal, + StringRef BaseInput, + StringRef Extension, + bool UseTemporary, + bool CreateMissingDirectories, + std::string *ResultPathName, + std::string *TempPathName); /// } /// @name Initialization Utility Methods @@ -662,6 +664,10 @@ public: SourceLocation ImportLoc, bool Complain); + bool hadModuleLoaderFatalFailure() const { + return ModuleLoader::HadFatalFailure; + } + }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h index fac05c5..f64773c 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h @@ -29,15 +29,16 @@ #include <string> #include <vector> -namespace clang { +namespace llvm { +namespace opt { +class ArgList; +} +} +namespace clang { class CompilerInvocation; class DiagnosticsEngine; -namespace driver { -class ArgList; -} - /// \brief Fill out Opts based on the options given in Args. /// /// Args must have been created from the OptTable returned by @@ -45,9 +46,9 @@ class ArgList; /// /// When errors are encountered, return false and, if Diags is non-null, /// report the error(s). -bool ParseDiagnosticArgs(DiagnosticOptions &Opts, driver::ArgList &Args, +bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags = 0); - + class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> { protected: /// Options controlling the language variant. diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h index 83976c3..fefb6f3 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h @@ -25,6 +25,7 @@ public: /// dependency, which can avoid some 'make' /// problems. unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list + unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info. /// The file to write dependency output to. std::string OutputFile; @@ -48,6 +49,7 @@ public: ShowHeaderIncludes = 0; UsePhonyTargets = 0; AddMissingHeaderDeps = 0; + PrintShowIncludes = 0; } }; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h index c67be92..a568ba0 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h @@ -94,6 +94,14 @@ protected: /// BeginSourceFileAction (and BeginSourceFile). virtual void EndSourceFileAction() {} + /// \brief Callback at the end of processing a single input, to determine + /// if the output files should be erased or not. + /// + /// By default it returns true if a compiler error occurred. + /// This is guaranteed to only be called following a successful call to + /// BeginSourceFileAction (and BeginSourceFile). + virtual bool shouldEraseOutputFiles(); + /// @} public: @@ -116,7 +124,7 @@ public: bool isCurrentFileAST() const { assert(!CurrentInput.isEmpty() && "No current file!"); - return CurrentASTUnit != 0; + return CurrentASTUnit.isValid(); } const FrontendInputFile &getCurrentInput() const { diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h index 1786190..f3d1276 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h @@ -56,12 +56,6 @@ protected: StringRef InFile); }; -class ASTDumpXMLAction : public ASTFrontendAction { -protected: - virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - StringRef InFile); -}; - class ASTViewAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, @@ -99,6 +93,7 @@ public: class GenerateModuleAction : public ASTFrontendAction { clang::Module *Module; + bool IsSystem; protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, @@ -111,6 +106,9 @@ protected: virtual bool hasASTFileSupport() const { return false; } public: + explicit GenerateModuleAction(bool IsSystem = false) + : ASTFrontendAction(), IsSystem(IsSystem) { } + virtual bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename); /// \brief Compute the AST consumer arguments that will be used to diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h index 0b05b74..312dbf1 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define FRONTENDSTART #include "clang/Basic/DiagnosticFrontendKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h index 234e344..4b321e8 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h @@ -26,7 +26,6 @@ namespace frontend { enum ActionKind { ASTDeclList, ///< Parse ASTs and list Decl nodes. ASTDump, ///< Parse ASTs and dump them. - ASTDumpXML, ///< Parse ASTs and dump them in XML. ASTPrint, ///< Parse ASTs and print them. ASTView, ///< Parse ASTs and view them in Graphviz. DumpRawTokens, ///< Dump out raw tokens. @@ -142,6 +141,8 @@ public: ///< global module index if available. unsigned GenerateGlobalModuleIndex : 1; ///< Whether we can generate the ///< global module index if needed. + unsigned ASTDumpLookups : 1; ///< Whether we include lookup table + ///< dumps in AST dumps. CodeCompleteOptions CodeCompleteOpts; @@ -157,9 +158,35 @@ public: /// \brief Enable migration to modern ObjC literals. ObjCMT_Literals = 0x1, /// \brief Enable migration to modern ObjC subscripting. - ObjCMT_Subscripting = 0x2 + ObjCMT_Subscripting = 0x2, + /// \brief Enable migration to modern ObjC readonly property. + ObjCMT_ReadonlyProperty = 0x4, + /// \brief Enable migration to modern ObjC readwrite property. + ObjCMT_ReadwriteProperty = 0x8, + /// \brief Enable migration to modern ObjC property. + ObjCMT_Property = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty), + /// \brief Enable annotation of ObjCMethods of all kinds. + ObjCMT_Annotation = 0x10, + /// \brief Enable migration of ObjC methods to 'instancetype'. + ObjCMT_Instancetype = 0x20, + /// \brief Enable migration to NS_ENUM/NS_OPTIONS macros. + ObjCMT_NsMacros = 0x40, + /// \brief Enable migration to add conforming protocols. + ObjCMT_ProtocolConformance = 0x80, + /// \brief prefer 'atomic' property over 'nonatomic'. + ObjCMT_AtomicProperty = 0x100, + /// \brief annotate property with NS_RETURNS_INNER_POINTER + ObjCMT_ReturnsInnerPointerProperty = 0x200, + /// \brief use NS_NONATOMIC_IOSONLY for property 'atomic' attribute + ObjCMT_NsAtomicIOSOnlyProperty = 0x400, + ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty | + ObjCMT_Annotation | ObjCMT_Instancetype | + ObjCMT_NsMacros | ObjCMT_ProtocolConformance | + ObjCMT_NsAtomicIOSOnlyProperty), + ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | ObjCMT_MigrateDecls) }; unsigned ObjCMTAction; + std::string ObjCMTWhiteListPath; std::string MTMigrateDir; std::string ARCMTMigrateReportOut; @@ -215,7 +242,7 @@ public: FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false), FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false), SkipFunctionBodies(false), UseGlobalModuleIndex(true), - GenerateGlobalModuleIndex(true), + GenerateGlobalModuleIndex(true), ASTDumpLookups(false), ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None), ProgramAction(frontend::ParseSyntaxOnly) {} diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h index 656aa57..c8d01b0 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h @@ -51,7 +51,8 @@ public: /// TextDiagnostic logic requires. static void printDiagnosticLevel(raw_ostream &OS, DiagnosticsEngine::Level Level, - bool ShowColors); + bool ShowColors, + bool CLFallbackMode = false); /// \brief Pretty-print a diagnostic message to a raw_ostream. /// diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h index 8830dce..dff56c3 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h @@ -17,10 +17,15 @@ #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Option/OptSpecifier.h" namespace llvm { class raw_fd_ostream; class Triple; + +namespace opt { +class ArgList; +} } namespace clang { @@ -86,9 +91,11 @@ void AttachDependencyFileGen(Preprocessor &PP, /// the default behavior used by -H. /// \param OutputPath - If non-empty, a path to write the header include /// information to, instead of writing to stderr. +/// \param ShowDepth - Whether to indent to show the nesting of the includes. +/// \param MSStyle - Whether to print in cl.exe /showIncludes style. void AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders = false, StringRef OutputPath = "", - bool ShowDepth = true); + bool ShowDepth = true, bool MSStyle = false); /// CacheTokens - Cache tokens for use with PCH. Note that this requires /// a seekable stream. @@ -104,6 +111,18 @@ createInvocationFromCommandLine(ArrayRef<const char *> Args, IntrusiveRefCntPtr<DiagnosticsEngine> Diags = IntrusiveRefCntPtr<DiagnosticsEngine>()); -} // end namespace clang +/// Return the value of the last argument as an integer, or a default. If Diags +/// is non-null, emits an error if the argument is given, but non-integral. +int getLastArgIntValue(const llvm::opt::ArgList &Args, + llvm::opt::OptSpecifier Id, int Default, + DiagnosticsEngine *Diags = 0); + +inline int getLastArgIntValue(const llvm::opt::ArgList &Args, + llvm::opt::OptSpecifier Id, int Default, + DiagnosticsEngine &Diags) { + return getLastArgIntValue(Args, Id, Default, &Diags); +} + +} // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/Index/CommentToXML.h b/contrib/llvm/tools/clang/include/clang/Index/CommentToXML.h new file mode 100644 index 0000000..8444b14 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Index/CommentToXML.h @@ -0,0 +1,50 @@ +//===--- CommentToXML.h - Convert comments to XML representation ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_COMMENTTOXML_H +#define LLVM_CLANG_INDEX_COMMENTTOXML_H + +#include "clang/Basic/LLVM.h" + +namespace clang { +class ASTContext; + +namespace comments { +class FullComment; +class HTMLTagComment; +} + +namespace index { +class SimpleFormatContext; + +class CommentToXMLConverter { + SimpleFormatContext *FormatContext; + unsigned FormatInMemoryUniqueId; + +public: + CommentToXMLConverter() : FormatContext(0), FormatInMemoryUniqueId(0) {} + + void convertCommentToHTML(const comments::FullComment *FC, + SmallVectorImpl<char> &HTML, + const ASTContext &Context); + + void convertHTMLTagNodeToText(const comments::HTMLTagComment *HTC, + SmallVectorImpl<char> &Text, + const ASTContext &Context); + + void convertCommentToXML(const comments::FullComment *FC, + SmallVectorImpl<char> &XML, + const ASTContext &Context); +}; + +} // namespace index +} // namespace clang + +#endif // LLVM_CLANG_INDEX_COMMENTTOXML_H + diff --git a/contrib/llvm/tools/clang/include/clang/Index/USRGeneration.h b/contrib/llvm/tools/clang/include/clang/Index/USRGeneration.h new file mode 100644 index 0000000..7b0fd50 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Index/USRGeneration.h @@ -0,0 +1,54 @@ +//===- USRGeneration.h - Routines for USR generation ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_USRGENERATION_H +#define LLVM_CLANG_INDEX_USRGENERATION_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { + class Decl; + +namespace index { + +static inline StringRef getUSRSpacePrefix() { + return "c:"; +} + +/// \brief Generate a USR for a Decl, including the prefix. +/// \returns true if the results should be ignored, false otherwise. +bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf); + +/// \brief Generate a USR fragment for an Objective-C class. +void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS); + +/// \brief Generate a USR fragment for an Objective-C class category. +void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS); + +/// \brief Generate a USR fragment for an Objective-C instance variable. The +/// complete USR can be created by concatenating the USR for the +/// encompassing class with this USR fragment. +void generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS); + +/// \brief Generate a USR fragment for an Objective-C method. +void generateUSRForObjCMethod(StringRef Sel, bool IsInstanceMethod, + raw_ostream &OS); + +/// \brief Generate a USR fragment for an Objective-C property. +void generateUSRForObjCProperty(StringRef Prop, raw_ostream &OS); + +/// \brief Generate a USR fragment for an Objective-C protocol. +void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS); + +} // namespace index +} // namespace clang + +#endif // LLVM_CLANG_IDE_USRGENERATION_H + diff --git a/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h b/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h index 261dfab..dff3e8c 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h @@ -16,6 +16,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" +#include "clang/Lex/ModuleMap.h" namespace clang { class HeaderMap; @@ -129,6 +130,11 @@ public: return (SrcMgr::CharacteristicKind)DirCharacteristic; } + /// \brief Whether this describes a system header directory. + bool isSystemHeaderDirectory() const { + return getDirCharacteristic() != SrcMgr::C_User; + } + /// \brief Whether this header map is building a framework or not. bool isIndexHeaderMap() const { return isHeaderMap() && IsIndexHeaderMap; @@ -158,7 +164,7 @@ public: const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule, + ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework) const; private: @@ -166,7 +172,7 @@ private: StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule, + ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemHeader) const; }; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h index 8a5a798..fb1a8620 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h @@ -53,6 +53,13 @@ struct HeaderFileInfo { /// \brief Whether this header is part of a module. unsigned isModuleHeader : 1; + + /// \brief Whether this header is part of the module that we are building. + unsigned isCompilingModuleHeader : 1; + + /// \brief Whether this header is part of the module that we are building. + /// This is an instance of ModuleMap::ModuleHeaderRole. + unsigned HeaderRole : 2; /// \brief Whether this structure is considered to already have been /// "resolved", meaning that it was loaded from the external source. @@ -93,8 +100,9 @@ struct HeaderFileInfo { HeaderFileInfo() : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), - External(false), isModuleHeader(false), Resolved(false), - IndexHeaderMapHeader(false), + External(false), isModuleHeader(false), isCompilingModuleHeader(false), + HeaderRole(ModuleMap::NormalHeader), + Resolved(false), IndexHeaderMapHeader(false), NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {} /// \brief Retrieve the controlling macro for this header file, if @@ -107,6 +115,16 @@ struct HeaderFileInfo { return isImport || isPragmaOnce || NumIncludes || ControllingMacro || ControllingMacroID; } + + /// \brief Get the HeaderRole properly typed. + ModuleMap::ModuleHeaderRole getHeaderRole() const { + return static_cast<ModuleMap::ModuleHeaderRole>(HeaderRole); + } + + /// \brief Set the HeaderRole properly typed. + void setHeaderRole(ModuleMap::ModuleHeaderRole Role) { + HeaderRole = Role; + } }; /// \brief An external source of header file information, which may supply @@ -222,7 +240,7 @@ class HeaderSearch { public: HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, - FileManager &FM, DiagnosticsEngine &Diags, + SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target); ~HeaderSearch(); @@ -261,7 +279,7 @@ public: /// \brief Checks whether the map exists or not. bool HasIncludeAliasMap() const { - return IncludeAliases; + return IncludeAliases.isValid(); } /// \brief Map the source include name to the dest include name. @@ -354,7 +372,7 @@ public: const FileEntry *CurFileEnt, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule, + ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false); /// \brief Look up a subframework for the specified \#include file. @@ -368,7 +386,7 @@ public: const FileEntry *RelativeFileEnt, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule); + ModuleMap::KnownHeader *SuggestedModule); /// \brief Look up the specified framework name in our framework cache. /// \returns The DirectoryEntry it is in if we know, null otherwise. @@ -405,7 +423,9 @@ public: } /// \brief Mark the specified file as part of a module. - void MarkFileModuleHeader(const FileEntry *File); + void MarkFileModuleHeader(const FileEntry *File, + ModuleMap::ModuleHeaderRole Role, + bool IsCompiledModuleHeader); /// \brief Increment the count for the number of times the specified /// FileEntry has been entered. @@ -422,6 +442,11 @@ public: getFileInfo(File).ControllingMacro = ControllingMacro; } + /// \brief Return true if this is the first time encountering this header. + bool FirstTimeLexingFile(const FileEntry *File) { + return getFileInfo(File).NumIncludes == 1; + } + /// \brief Determine whether this file is intended to be safe from /// multiple inclusions, e.g., it has \#pragma once or a controlling /// macro. @@ -471,25 +496,33 @@ public: /// /// \param Root The "root" directory, at which we should stop looking for /// module maps. - bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root); + /// + /// \param IsSystem Whether the directories we're looking at are system + /// header directories. + bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root, + bool IsSystem); /// \brief Retrieve the module that corresponds to the given file, if any. /// /// \param File The header that we wish to map to a module. - Module *findModuleForHeader(const FileEntry *File) const; + ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File) const; /// \brief Read the contents of the given module map file. /// /// \param File The module map file. + /// \param IsSystem Whether this file is in a system header directory. /// /// \returns true if an error occurred, false otherwise. - bool loadModuleMapFile(const FileEntry *File); + bool loadModuleMapFile(const FileEntry *File, bool IsSystem); /// \brief Collect the set of all known, top-level modules. /// /// \param Modules Will be filled with the set of known, top-level modules. void collectAllModules(SmallVectorImpl<Module *> &Modules); - + + /// \brief Load all known, top-level system modules. + void loadTopLevelSystemModules(); + private: /// \brief Retrieve a module with the given name, which may be part of the /// given framework. @@ -516,9 +549,6 @@ public: unsigned header_file_size() const { return FileInfo.size(); } - // Used by ASTReader. - void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID); - /// \brief Return the HeaderFileInfo structure for the specified FileEntry. const HeaderFileInfo &getFileInfo(const FileEntry *FE) const { return const_cast<HeaderSearch*>(this)->getFileInfo(FE); @@ -577,18 +607,21 @@ private: /// /// \param DirName The name of the directory where we will look for a module /// map file. + /// \param IsSystem Whether this is a system header directory. /// /// \returns The result of attempting to load the module map file from the /// named directory. - LoadModuleMapResult loadModuleMapFile(StringRef DirName); + LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem); /// \brief Try to load the module map file in the given directory. /// /// \param Dir The directory where we will look for a module map file. + /// \param IsSystem Whether this is a system header directory. /// /// \returns The result of attempting to load the module map file from the /// named directory. - LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir); + LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir, + bool IsSystem); /// \brief Return the HeaderFileInfo structure for the specified FileEntry. HeaderFileInfo &getFileInfo(const FileEntry *FE); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h index afce5ba..0b21c0d 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h @@ -95,6 +95,9 @@ public: /// Note: Only used for testing! unsigned DisableModuleHash : 1; + /// \brief Interpret module maps. This option is implied by full modules. + unsigned ModuleMaps : 1; + /// \brief The interval (in seconds) between pruning operations. /// /// This operation is expensive, because it requires Clang to walk through @@ -117,6 +120,9 @@ public: /// of computing the module hash. llvm::SetVector<std::string> ModulesIgnoreMacros; + /// \brief The set of user-provided module-map-files. + llvm::SetVector<std::string> ModuleMapFiles; + /// Include the compiler builtin includes. unsigned UseBuiltinIncludes : 1; @@ -134,7 +140,7 @@ public: public: HeaderSearchOptions(StringRef _Sysroot = "/") - : Sysroot(_Sysroot), DisableModuleHash(0), + : Sysroot(_Sysroot), DisableModuleHash(0), ModuleMaps(0), ModuleCachePruneInterval(7*24*60*60), ModuleCachePruneAfter(31*24*60*60), UseBuiltinIncludes(true), diff --git a/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h index 41b9396..85424aa 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/LexDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define LEXSTART #include "clang/Basic/DiagnosticLexKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h b/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h index cb4f57f..f456fa9 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Lexer.h @@ -80,6 +80,12 @@ class Lexer : public PreprocessorLexer { // line" flag set on it. bool IsAtStartOfLine; + bool IsAtPhysicalStartOfLine; + + bool HasLeadingSpace; + + bool HasLeadingEmptyMacro; + // CurrentConflictMarkerState - The kind of conflict marker we are handling. ConflictMarkerKind CurrentConflictMarkerState; @@ -127,31 +133,21 @@ public: /// from. Currently this is only used by _Pragma handling. SourceLocation getFileLoc() const { return FileLoc; } +private: /// Lex - Return the next token in the file. If this is the end of file, it /// return the tok::eof token. This implicitly involves the preprocessor. - void Lex(Token &Result) { - // Start a new token. - Result.startToken(); - - // NOTE, any changes here should also change code after calls to - // Preprocessor::HandleDirective - if (IsAtStartOfLine) { - Result.setFlag(Token::StartOfLine); - IsAtStartOfLine = false; - } - - // Get a token. Note that this may delete the current lexer if the end of - // file is reached. - LexTokenInternal(Result); - } + bool Lex(Token &Result); +public: /// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma. bool isPragmaLexer() const { return Is_PragmaLexer; } +private: /// IndirectLex - An indirect call to 'Lex' that can be invoked via /// the PreprocessorLexer interface. void IndirectLex(Token &Result) { Lex(Result); } +public: /// LexFromRawLexer - Lex a token from a designated raw lexer (one with no /// associated preprocessor object. Return true if the 'next character to /// read' pointer points at the end of the lexer buffer, false otherwise. @@ -202,7 +198,10 @@ public: /// lexer has nothing to reset to. void resetExtendedTokenMode(); - const char *getBufferStart() const { return BufferStart; } + /// Gets source code buffer. + StringRef getBuffer() const { + return StringRef(BufferStart, BufferEnd - BufferStart); + } /// ReadToEndOfLine - Read the rest of the current preprocessor line as an /// uninterpreted string. This switches the lexer out of directive mode. @@ -285,7 +284,8 @@ public: /// \returns true if there was a failure, false on success. static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, - const LangOptions &LangOpts); + const LangOptions &LangOpts, + bool IgnoreWhiteSpace = false); /// \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 @@ -443,12 +443,14 @@ private: /// LexTokenInternal - Internal interface to lex a preprocessing token. Called /// by Lex. /// - void LexTokenInternal(Token &Result); + bool LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine); + + bool CheckUnicodeWhitespace(Token &Result, uint32_t C, const char *CurPtr); /// Given that a token begins with the Unicode character \p C, figure out /// what kind of token it is and dispatch to the appropriate lexing helper /// function. - void LexUnicode(Token &Result, uint32_t C, const char *CurPtr); + bool LexUnicode(Token &Result, uint32_t C, const char *CurPtr); /// FormTokenWithChars - When we lex a token, we have identified a span /// starting at BufferPtr, going to TokEnd that forms the token. This method @@ -566,23 +568,28 @@ private: void SkipBytes(unsigned Bytes, bool StartOfLine); - const char *LexUDSuffix(Token &Result, const char *CurPtr); - + void PropagateLineStartLeadingSpaceInfo(Token &Result); + + const char *LexUDSuffix(Token &Result, const char *CurPtr, + bool IsStringLiteral); + // Helper functions to lex the remainder of a token of the specific type. - void LexIdentifier (Token &Result, const char *CurPtr); - void LexNumericConstant (Token &Result, const char *CurPtr); - void LexStringLiteral (Token &Result, const char *CurPtr, + bool LexIdentifier (Token &Result, const char *CurPtr); + bool LexNumericConstant (Token &Result, const char *CurPtr); + bool LexStringLiteral (Token &Result, const char *CurPtr, tok::TokenKind Kind); - void LexRawStringLiteral (Token &Result, const char *CurPtr, + bool LexRawStringLiteral (Token &Result, const char *CurPtr, tok::TokenKind Kind); - void LexAngledStringLiteral(Token &Result, const char *CurPtr); - void LexCharConstant (Token &Result, const char *CurPtr, + bool LexAngledStringLiteral(Token &Result, const char *CurPtr); + bool LexCharConstant (Token &Result, const char *CurPtr, tok::TokenKind Kind); bool LexEndOfFile (Token &Result, const char *CurPtr); - - bool SkipWhitespace (Token &Result, const char *CurPtr); - bool SkipLineComment (Token &Result, const char *CurPtr); - bool SkipBlockComment (Token &Result, const char *CurPtr); + bool SkipWhitespace (Token &Result, const char *CurPtr, + bool &TokAtPhysicalStartOfLine); + bool SkipLineComment (Token &Result, const char *CurPtr, + bool &TokAtPhysicalStartOfLine); + bool SkipBlockComment (Token &Result, const char *CurPtr, + bool &TokAtPhysicalStartOfLine); bool SaveLineComment (Token &Result, const char *CurPtr); bool IsStartOfConflictMarker(const char *CurPtr); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h b/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h index b1430cc..64d5aa2 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/LiteralSupport.h @@ -79,6 +79,8 @@ public: return SuffixBegin - ThisTokBegin; } + static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix); + unsigned getRadix() const { return radix; } /// GetIntegerValue - Convert this numeric literal value to an APInt that @@ -98,10 +100,18 @@ private: void ParseNumberStartingWithZero(SourceLocation TokLoc); + static bool isDigitSeparator(char C) { return C == '\''; } + + enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits }; + + /// \brief Ensure that we don't have a digit separator here. + void checkSeparator(SourceLocation TokLoc, const char *Pos, + CheckSeparatorKind IsAfterDigits); + /// SkipHexDigits - Read and skip over any hex digits, up to End. /// Return a pointer to the first non-hex digit or End. const char *SkipHexDigits(const char *ptr) { - while (ptr != ThisTokEnd && isHexDigit(*ptr)) + while (ptr != ThisTokEnd && (isHexDigit(*ptr) || isDigitSeparator(*ptr))) ptr++; return ptr; } @@ -109,7 +119,8 @@ private: /// SkipOctalDigits - Read and skip over any octal digits, up to End. /// Return a pointer to the first non-hex digit or End. const char *SkipOctalDigits(const char *ptr) { - while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7'))) + while (ptr != ThisTokEnd && + ((*ptr >= '0' && *ptr <= '7') || isDigitSeparator(*ptr))) ptr++; return ptr; } @@ -117,7 +128,7 @@ private: /// SkipDigits - Read and skip over any digits, up to End. /// Return a pointer to the first non-hex digit or End. const char *SkipDigits(const char *ptr) { - while (ptr != ThisTokEnd && isDigit(*ptr)) + while (ptr != ThisTokEnd && (isDigit(*ptr) || isDigitSeparator(*ptr))) ptr++; return ptr; } @@ -125,7 +136,8 @@ private: /// SkipBinaryDigits - Read and skip over any binary digits, up to End. /// Return a pointer to the first non-binary digit or End. const char *SkipBinaryDigits(const char *ptr) { - while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1')) + while (ptr != ThisTokEnd && + (*ptr == '0' || *ptr == '1' || isDigitSeparator(*ptr))) ptr++; return ptr; } diff --git a/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h index 64323b7..8cb370e 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h @@ -251,7 +251,7 @@ public: return ReplacementTokens[Tok]; } - typedef SmallVector<Token, 8>::const_iterator tokens_iterator; + typedef SmallVectorImpl<Token>::const_iterator tokens_iterator; tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); } tokens_iterator tokens_end() const { return ReplacementTokens.end(); } bool tokens_empty() const { return ReplacementTokens.empty(); } @@ -421,7 +421,7 @@ public: bool isValid() const { return DefDirective != 0; } bool isInvalid() const { return !isValid(); } - operator bool() const { return isValid(); } + LLVM_EXPLICIT operator bool() const { return isValid(); } inline DefInfo getPreviousDefinition(bool AllowHidden = false); const DefInfo getPreviousDefinition(bool AllowHidden = false) const { diff --git a/contrib/llvm/tools/clang/include/clang/Lex/ModuleLoader.h b/contrib/llvm/tools/clang/include/clang/Lex/ModuleLoader.h index 3acf915..254ab36 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/ModuleLoader.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/ModuleLoader.h @@ -54,6 +54,8 @@ public: /// then loading that module. class ModuleLoader { public: + ModuleLoader() : HadFatalFailure(false) {} + virtual ~ModuleLoader(); /// \brief Attempt to load the given module. @@ -85,6 +87,8 @@ public: Module::NameVisibilityKind Visibility, SourceLocation ImportLoc, bool Complain) = 0; + + bool HadFatalFailure; }; } diff --git a/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h b/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h index dc75f18..3a17157 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h @@ -37,7 +37,7 @@ class HeaderSearch; class ModuleMapParser; class ModuleMap { - SourceManager *SourceMgr; + SourceManager &SourceMgr; IntrusiveRefCntPtr<DiagnosticsEngine> Diags; const LangOptions &LangOpts; const TargetInfo *Target; @@ -52,37 +52,64 @@ class ModuleMap { /// These are always simple C language options. LangOptions MMapLangOpts; + // The module that we are building; related to \c LangOptions::CurrentModule. + Module *CompilingModule; + +public: + // The module that the .cc source file is associated with. + Module *SourceModule; + std::string SourceModuleName; + +private: /// \brief The top-level modules that are known. llvm::StringMap<Module *> Modules; +public: + /// \brief Describes the role of a module header. + enum ModuleHeaderRole { + /// \brief This header is normally included in the module. + NormalHeader, + /// \brief This header is included but private. + PrivateHeader, + /// \brief This header is explicitly excluded from the module. + ExcludedHeader + // Caution: Adding an enumerator needs other changes. + // Adjust the number of bits for KnownHeader::Storage. + // Adjust the bitfield HeaderFileInfo::HeaderRole size. + // Adjust the HeaderFileInfoTrait::ReadData streaming. + // Adjust the HeaderFileInfoTrait::EmitData streaming. + }; + /// \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; + llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage; public: - KnownHeader() : Storage(0, false) { } - KnownHeader(Module *M, bool Excluded) : Storage(M, Excluded) { } + KnownHeader() : Storage(0, NormalHeader) { } + KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { } /// \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 The role of this header within the module. + ModuleHeaderRole getRole() const { return Storage.getInt(); } /// \brief Whether this header is available in the module. bool isAvailable() const { - return !isExcluded() && getModule()->isAvailable(); + return getRole() != ExcludedHeader && getModule()->isAvailable(); } // \brief Whether this known header is valid (i.e., it has an // associated module). - operator bool() const { return Storage.getPointer() != 0; } + LLVM_EXPLICIT operator bool() const { return Storage.getPointer() != 0; } }; - typedef llvm::DenseMap<const FileEntry *, KnownHeader> HeadersMap; +private: + typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> > + HeadersMap; - /// \brief Mapping from each header to the module that owns the contents of the + /// \brief Mapping from each header to the module that owns the contents of /// that header. HeadersMap Headers; @@ -151,9 +178,9 @@ class ModuleMap { public: /// \brief Construct a new module map. /// - /// \param FileMgr The file manager used to find module files and headers. - /// This file manager should be shared with the header-search mechanism, since - /// they will refer to the same headers. + /// \param SourceMgr The source manager used to find module files and headers. + /// This source manager should be shared with the header-search mechanism, + /// since they will refer to the same headers. /// /// \param DC A diagnostic consumer that will be cloned for use in generating /// diagnostics. @@ -161,7 +188,7 @@ public: /// \param LangOpts Language options for this translation unit. /// /// \param Target The target for this translation unit. - ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC, + ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo); @@ -182,9 +209,15 @@ public: /// /// \param File The header file that is likely to be included. /// - /// \returns The module that owns the given header file, or null to indicate + /// \param RequestingModule Specifies the module the header is intended to be + /// used from. Used to disambiguate if a header is present in multiple + /// modules. + /// + /// \returns The module KnownHeader, which provides the module that owns the + /// given header file. The KnownHeader is default constructed to indicate /// that no module owns this header file. - Module *findModuleForHeader(const FileEntry *File); + KnownHeader findModuleForHeader(const FileEntry *File, + Module *RequestingModule = NULL); /// \brief Determine whether the given header is part of a module /// marked 'unavailable'. @@ -278,6 +311,16 @@ public: /// false otherwise. bool resolveExports(Module *Mod, bool Complain); + /// \brief Resolve all of the unresolved uses in the given module. + /// + /// \param Mod The module whose uses should be resolved. + /// + /// \param Complain Whether to emit diagnostics for failures. + /// + /// \returns true if any errors were encountered while resolving uses, + /// false otherwise. + bool resolveUses(Module *Mod, bool Complain); + /// \brief Resolve all of the unresolved conflicts in the given module. /// /// \param Mod The module whose conflicts should be resolved. @@ -307,17 +350,20 @@ public: void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir); /// \brief Adds this header to the given module. - /// \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); + /// \param Role The role of the header wrt the module. + void addHeader(Module *Mod, const FileEntry *Header, + ModuleHeaderRole Role); /// \brief Parse the given module map file, and record any modules we /// encounter. /// /// \param File The file to be parsed. /// + /// \param IsSystem Whether this module map file is in a system header + /// directory, and therefore should be considered a system module. + /// /// \returns true if an error occurred, false otherwise. - bool parseModuleMapFile(const FileEntry *File); + bool parseModuleMapFile(const FileEntry *File, bool IsSystem); /// \brief Dump the contents of the module map, for debugging purposes. void dump(); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/MultipleIncludeOpt.h b/contrib/llvm/tools/clang/include/clang/Lex/MultipleIncludeOpt.h index a2a5a77..b532bf8 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/MultipleIncludeOpt.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/MultipleIncludeOpt.h @@ -15,6 +15,8 @@ #ifndef LLVM_CLANG_MULTIPLEINCLUDEOPT_H #define LLVM_CLANG_MULTIPLEINCLUDEOPT_H +#include "clang/Basic/SourceLocation.h" + namespace clang { class IdentifierInfo; @@ -32,6 +34,11 @@ class MultipleIncludeOpt { /// \#endif can be easily detected. bool ReadAnyTokens; + /// ImmediatelyAfterTopLevelIfndef - This is true when the only tokens + /// processed in the file so far is an #ifndef and an identifier. Used in + /// the detection of header guards in a file. + bool ImmediatelyAfterTopLevelIfndef; + /// ReadAnyTokens - This is set to false when a file is first opened and true /// any time a token is returned to the client or a (non-multiple-include) /// directive is parsed. When the final #endif is parsed this is reset back @@ -42,11 +49,36 @@ class MultipleIncludeOpt { /// TheMacro - The controlling macro for a file, if valid. /// const IdentifierInfo *TheMacro; + + /// DefinedMacro - The macro defined right after TheMacro, if any. + const IdentifierInfo *DefinedMacro; + + SourceLocation MacroLoc; + SourceLocation DefinedLoc; public: MultipleIncludeOpt() { ReadAnyTokens = false; + ImmediatelyAfterTopLevelIfndef = false; DidMacroExpansion = false; TheMacro = 0; + DefinedMacro = 0; + } + + SourceLocation GetMacroLocation() const { + return MacroLoc; + } + + SourceLocation GetDefinedLocation() const { + return DefinedLoc; + } + + void resetImmediatelyAfterTopLevelIfndef() { + ImmediatelyAfterTopLevelIfndef = false; + } + + void SetDefinedMacro(IdentifierInfo *M, SourceLocation Loc) { + DefinedMacro = M; + DefinedLoc = Loc; } /// Invalidate - Permanently mark this file as not being suitable for the @@ -55,6 +87,8 @@ public: // If we have read tokens but have no controlling macro, the state-machine // below can never "accept". ReadAnyTokens = true; + ImmediatelyAfterTopLevelIfndef = false; + DefinedMacro = 0; TheMacro = 0; } @@ -63,8 +97,17 @@ public: /// the "ifndef x" would count as reading tokens. bool getHasReadAnyTokensVal() const { return ReadAnyTokens; } + /// getImmediatelyAfterTopLevelIfndef - returns true if the last directive + /// was an #ifndef at the beginning of the file. + bool getImmediatelyAfterTopLevelIfndef() const { + return ImmediatelyAfterTopLevelIfndef; + } + // If a token is read, remember that we have seen a side-effect in this file. - void ReadToken() { ReadAnyTokens = true; } + void ReadToken() { + ReadAnyTokens = true; + ImmediatelyAfterTopLevelIfndef = false; + } /// ExpandedMacro - When a macro is expanded with this lexer as the current /// buffer, this method is called to disable the MIOpt if needed. @@ -77,7 +120,7 @@ public: /// ensures that this is only called if there are no tokens read before the /// \#ifndef. The caller is required to do this, because reading the \#if /// line obviously reads in in tokens. - void EnterTopLevelIFNDEF(const IdentifierInfo *M) { + void EnterTopLevelIfndef(const IdentifierInfo *M, SourceLocation Loc) { // If the macro is already set, this is after the top-level #endif. if (TheMacro) return Invalidate(); @@ -91,7 +134,9 @@ public: // Remember that we're in the #if and that we have the macro. ReadAnyTokens = true; + ImmediatelyAfterTopLevelIfndef = true; TheMacro = M; + MacroLoc = Loc; } /// \brief Invoked when a top level conditional (except \#ifndef) is found. @@ -111,6 +156,7 @@ public: // At this point, we haven't "read any tokens" but we do have a controlling // macro. ReadAnyTokens = false; + ImmediatelyAfterTopLevelIfndef = false; } /// \brief Once the entire file has been lexed, if there is a controlling @@ -122,6 +168,12 @@ public: return TheMacro; return 0; } + + /// \brief If the ControllingMacro is followed by a macro definition, return + /// the macro that was defined. + const IdentifierInfo *GetDefinedMacro() const { + return DefinedMacro; + } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h index db2ecd2..0e11218 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h @@ -19,6 +19,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Lex/DirectoryLookup.h" #include "clang/Lex/ModuleLoader.h" +#include "clang/Lex/Pragma.h" #include "llvm/ADT/StringRef.h" #include <string> @@ -155,11 +156,23 @@ public: virtual void Ident(SourceLocation Loc, const std::string &str) { } + /// \brief Callback invoked when start reading any pragma directive. + virtual void PragmaDirective(SourceLocation Loc, + PragmaIntroducerKind Introducer) { + } + /// \brief Callback invoked when a \#pragma comment directive is read. virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, const std::string &Str) { } + /// \brief Callback invoked when a \#pragma detect_mismatch directive is + /// read. + virtual void PragmaDetectMismatch(SourceLocation Loc, + const std::string &Name, + const std::string &Value) { + } + /// \brief Callback invoked when a \#pragma clang __debug directive is read. /// \param Loc The location of the debug directive. /// \param DebugType The identifier following __debug. @@ -204,6 +217,26 @@ public: diag::Mapping mapping, StringRef Str) { } + /// \brief Called when an OpenCL extension is either disabled or + /// enabled with a pragma. + virtual void PragmaOpenCLExtension(SourceLocation NameLoc, + const IdentifierInfo *Name, + SourceLocation StateLoc, unsigned State) { + } + + /// \brief Callback invoked when a \#pragma warning directive is read. + virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, + ArrayRef<int> Ids) { + } + + /// \brief Callback invoked when a \#pragma warning(push) directive is read. + virtual void PragmaWarningPush(SourceLocation Loc, int Level) { + } + + /// \brief Callback invoked when a \#pragma warning(pop) directive is read. + virtual void PragmaWarningPop(SourceLocation Loc) { + } + /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a /// macro invocation is found. virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, @@ -224,7 +257,8 @@ public: /// \brief Hook called whenever the 'defined' operator is seen. /// \param MD The MacroDirective if the name was a macro, null otherwise. - virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD) { + virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD, + SourceRange Range) { } /// \brief Hook called when a source range is skipped. @@ -236,18 +270,21 @@ public: /// \brief Hook called whenever an \#if is seen. /// \param Loc the source location of the directive. /// \param ConditionRange The SourceRange of the expression being tested. + /// \param ConditionValue The evaluated value of the condition. /// // FIXME: better to pass in a list (or tree!) of Tokens. - virtual void If(SourceLocation Loc, SourceRange ConditionRange) { + virtual void If(SourceLocation Loc, SourceRange ConditionRange, + bool ConditionValue) { } /// \brief Hook called whenever an \#elif is seen. /// \param Loc the source location of the directive. /// \param ConditionRange The SourceRange of the expression being tested. + /// \param ConditionValue The evaluated value of the condition. /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive. // FIXME: better to pass in a list (or tree!) of Tokens. virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, - SourceLocation IfLoc) { + bool ConditionValue, SourceLocation IfLoc) { } /// \brief Hook called whenever an \#ifdef is seen. @@ -352,6 +389,13 @@ public: Second->PragmaComment(Loc, Kind, Str); } + virtual void PragmaDetectMismatch(SourceLocation Loc, + const std::string &Name, + const std::string &Value) { + First->PragmaDetectMismatch(Loc, Name, Value); + Second->PragmaDetectMismatch(Loc, Name, Value); + } + virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str) { First->PragmaMessage(Loc, Namespace, Kind, Str); @@ -376,6 +420,29 @@ public: Second->PragmaDiagnostic(Loc, Namespace, mapping, Str); } + virtual void PragmaOpenCLExtension(SourceLocation NameLoc, + const IdentifierInfo *Name, + SourceLocation StateLoc, unsigned State) { + First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); + Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State); + } + + virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec, + ArrayRef<int> Ids) { + First->PragmaWarning(Loc, WarningSpec, Ids); + Second->PragmaWarning(Loc, WarningSpec, Ids); + } + + virtual void PragmaWarningPush(SourceLocation Loc, int Level) { + First->PragmaWarningPush(Loc, Level); + Second->PragmaWarningPush(Loc, Level); + } + + virtual void PragmaWarningPop(SourceLocation Loc) { + First->PragmaWarningPop(Loc); + Second->PragmaWarningPop(Loc); + } + virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, SourceRange Range, const MacroArgs *Args) { First->MacroExpands(MacroNameTok, MD, Range, Args); @@ -393,9 +460,10 @@ public: Second->MacroUndefined(MacroNameTok, MD); } - virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD) { - First->Defined(MacroNameTok, MD); - Second->Defined(MacroNameTok, MD); + virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD, + SourceRange Range) { + First->Defined(MacroNameTok, MD, Range); + Second->Defined(MacroNameTok, MD, Range); } virtual void SourceRangeSkipped(SourceRange Range) { @@ -404,16 +472,17 @@ public: } /// \brief Hook called whenever an \#if is seen. - virtual void If(SourceLocation Loc, SourceRange ConditionRange) { - First->If(Loc, ConditionRange); - Second->If(Loc, ConditionRange); + virtual void If(SourceLocation Loc, SourceRange ConditionRange, + bool ConditionValue) { + First->If(Loc, ConditionRange, ConditionValue); + Second->If(Loc, ConditionRange, ConditionValue); } - /// \brief Hook called whenever an \#if is seen. + /// \brief Hook called whenever an \#elif is seen. virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, - SourceLocation IfLoc) { - First->Elif(Loc, ConditionRange, IfLoc); - Second->Elif(Loc, ConditionRange, IfLoc); + bool ConditionValue, SourceLocation IfLoc) { + First->Elif(Loc, ConditionRange, ConditionValue, IfLoc); + Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc); } /// \brief Hook called whenever an \#ifdef is seen. diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PPConditionalDirectiveRecord.h b/contrib/llvm/tools/clang/include/clang/Lex/PPConditionalDirectiveRecord.h index b9a2252..54a132d 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PPConditionalDirectiveRecord.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PPConditionalDirectiveRecord.h @@ -86,9 +86,10 @@ public: SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const; private: - virtual void If(SourceLocation Loc, SourceRange ConditionRange); + virtual void If(SourceLocation Loc, SourceRange ConditionRange, + bool ConditionValue); virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, - SourceLocation IfLoc); + bool ConditionValue, SourceLocation IfLoc); virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDirective *MD); virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h index a9276e8..d748bc1 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PTHLexer.h @@ -68,7 +68,7 @@ public: ~PTHLexer() {} /// Lex - Return the next token. - void Lex(Token &Tok); + bool Lex(Token &Tok); void getEOF(Token &Tok); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h index db74352..2584340 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h @@ -576,7 +576,8 @@ namespace clang { virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDirective *MD); /// \brief Hook called whenever the 'defined' operator is seen. - virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD); + virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD, + SourceRange Range); void addMacroExpansion(const Token &Id, const MacroInfo *MI, SourceRange Range); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h index c598177..223fd47 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h @@ -20,6 +20,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/MacroInfo.h" +#include "clang/Lex/ModuleMap.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/PTHLexer.h" #include "clang/Lex/PTHManager.h" @@ -221,7 +222,10 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \brief The module import path that we're currently processing. SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath; - + + /// \brief Whether the last token we lexed was an '@'. + bool LastTokenWasAt; + /// \brief Whether the module import expectes an identifier next. Otherwise, /// it expects a '.' or ';'. bool ModuleImportExpectsIdentifier; @@ -457,6 +461,10 @@ public: /// \brief Retrieve the module loader associated with this preprocessor. ModuleLoader &getModuleLoader() const { return TheModuleLoader; } + bool hadModuleLoaderFatalFailure() const { + return TheModuleLoader.HadFatalFailure; + } + /// \brief True if we are currently preprocessing a #if or #elif directive bool isParsingIfOrElifDirective() const { return ParsingIfOrElifDirective; @@ -711,17 +719,8 @@ public: /// caching of tokens is on. bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); } - /// Lex - To lex a token from the preprocessor, just pull a token from the - /// current lexer or macro object. - void Lex(Token &Result) { - switch (CurLexerKind) { - case CLK_Lexer: CurLexer->Lex(Result); break; - case CLK_PTHLexer: CurPTHLexer->Lex(Result); break; - case CLK_TokenLexer: CurTokenLexer->Lex(Result); break; - case CLK_CachingLexer: CachingLex(Result); break; - case CLK_LexAfterModuleImport: LexAfterModuleImport(Result); break; - } - } + /// Lex - Lex the next token for this preprocessor. + void Lex(Token &Result); void LexAfterModuleImport(Token &Result); @@ -828,6 +827,13 @@ public: AnnotatePreviousCachedTokens(Tok); } + /// Get the location of the last cached token, suitable for setting the end + /// location of an annotation token. + SourceLocation getLastCachedTokenLocation() const { + assert(CachedLexPos != 0); + return CachedTokens[CachedLexPos-1].getLocation(); + } + /// \brief Replace the last token with an annotation token. /// /// Like AnnotateCachedTokens(), this routine replaces an @@ -989,8 +995,9 @@ public: /// \brief Relex the token at the specified location. /// \returns true if there was a failure, false on success. - bool getRawToken(SourceLocation Loc, Token &Result) { - return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts); + bool getRawToken(SourceLocation Loc, Token &Result, + bool IgnoreWhiteSpace = false) { + return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts, IgnoreWhiteSpace); } /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant @@ -1155,7 +1162,10 @@ public: /// identifier and has filled in the tokens IdentifierInfo member. This /// callback potentially macro expands it or turns it into a named token (like /// 'for'). - void HandleIdentifier(Token &Identifier); + /// + /// \returns true if we actually computed a token, false if we need to + /// lex again. + bool HandleIdentifier(Token &Identifier); /// HandleEndOfFile - This callback is invoked when the lexer hits the end of @@ -1216,12 +1226,12 @@ public: /// /// Returns null on failure. \p isAngled indicates whether the file /// reference is for system \#include's or not (i.e. using <> instead of ""). - const FileEntry *LookupFile(StringRef Filename, + const FileEntry *LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - Module **SuggestedModule, + ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false); /// GetCurLookup - The DirectoryLookup structure used to find the current @@ -1273,6 +1283,8 @@ private: IncludeMacroStack.pop_back(); } + void PropagateLineStartLeadingSpaceInfo(Token &Result); + /// \brief Allocate a new MacroInfo object. MacroInfo *AllocateMacroInfo(); @@ -1329,7 +1341,7 @@ private: /// HandleMacroExpandedIdentifier - If an identifier token is read that is to /// be expanded as a macro, handle it and return the next token as 'Tok'. If - /// the macro should not be expanded return true, otherwise return false. + /// we lexed a token, return true; otherwise the caller should lex again. bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD); /// \brief Cache macro expanded tokens for TokenLexers. @@ -1400,7 +1412,7 @@ private: bool InCachingLexMode() const { // If the Lexer pointers are 0 and IncludeMacroStack is empty, it means // that we are past EOF, not that we are in CachingLex mode. - return CurPPLexer == 0 && CurTokenLexer == 0 && CurPTHLexer == 0 && + return !CurPPLexer && !CurTokenLexer && !CurPTHLexer && !IncludeMacroStack.empty(); } void EnterCachingLexMode(); @@ -1432,8 +1444,32 @@ private: void HandleImportDirective(SourceLocation HashLoc, Token &Tok); void HandleMicrosoftImportDirective(Token &Tok); + // Module inclusion testing. + /// \brief Find the module for the source or header file that \p FilenameLoc + /// points to. + Module *getModuleForLocation(SourceLocation FilenameLoc); + + /// \brief Verify that a private header is included only from within its + /// module. + bool violatesPrivateInclude(Module *RequestingModule, + const FileEntry *IncFileEnt, + ModuleMap::ModuleHeaderRole Role, + Module *RequestedModule); + + /// \brief Verify that a module includes headers only from modules that it + /// has declared that it uses. + bool violatesUseDeclarations(Module *RequestingModule, + Module *RequestedModule); + + /// \brief Verify that it is legal for the source file that \p FilenameLoc + /// points to to include the file \p Filename. + /// + /// Tries to reuse \p IncFileEnt. + void verifyModuleInclude(SourceLocation FilenameLoc, StringRef Filename, + const FileEntry *IncFileEnt); + // Macro handling. - void HandleDefineDirective(Token &Tok); + void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef); void HandleUndefDirective(Token &Tok); // Conditional Inclusion. @@ -1445,7 +1481,8 @@ private: void HandleElifDirective(Token &Tok); // Pragmas. - void HandlePragmaDirective(unsigned Introducer); + void HandlePragmaDirective(SourceLocation IntroducerLoc, + PragmaIntroducerKind Introducer); public: void HandlePragmaOnce(Token &OnceTok); void HandlePragmaMark(); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h index 20fb8a0..27a8df4 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessorLexer.h @@ -111,9 +111,9 @@ protected: /// stack, returning information about it. If the conditional stack is empty, /// this returns true and does not fill in the arguments. bool popConditionalLevel(PPConditionalInfo &CI) { - if (ConditionalStack.empty()) return true; - CI = ConditionalStack.back(); - ConditionalStack.pop_back(); + if (ConditionalStack.empty()) + return true; + CI = ConditionalStack.pop_back_val(); return false; } diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Token.h b/contrib/llvm/tools/clang/include/clang/Lex/Token.h index bcbe9c9..4f6391d 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Token.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Token.h @@ -71,13 +71,16 @@ public: // Various flags set per token: enum TokenFlags { - StartOfLine = 0x01, // At start of line or only after whitespace. - LeadingSpace = 0x02, // Whitespace exists before this token. + StartOfLine = 0x01, // At start of line or only after whitespace + // (considering the line after macro expansion). + LeadingSpace = 0x02, // Whitespace exists before this token (considering + // whitespace after macro expansion). DisableExpand = 0x04, // This identifier may never be macro expanded. NeedsCleaning = 0x08, // Contained an escaped newline or trigraph. LeadingEmptyMacro = 0x10, // Empty macro exists before this token. HasUDSuffix = 0x20, // This string or character literal has a ud-suffix. - HasUCN = 0x40 // This identifier contains a UCN. + HasUCN = 0x40, // This identifier contains a UCN. + IgnoredComma = 0x80 // This comma is not a macro argument separator (MS). }; tok::TokenKind getKind() const { return (tok::TokenKind)Kind; } diff --git a/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h index 090402a..7c8cfd0 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h @@ -136,7 +136,7 @@ public: unsigned isNextTokenLParen() const; /// Lex - Lex and return a token from this macro stream. - void Lex(Token &Tok); + bool Lex(Token &Tok); /// isParsingPreprocessorDirective - Return true if we are in the middle of a /// preprocessor directive. @@ -181,6 +181,8 @@ private: /// macro definition. void updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc, Token *begin_tokens, Token *end_tokens); + + void PropagateLineStartLeadingSpaceInfo(Token &Result); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h index 0d47292..b593806 100644 --- a/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Parse/ParseDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define PARSESTART #include "clang/Basic/DiagnosticParseKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h index 1029a90..bd49988 100644 --- a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h +++ b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h @@ -45,6 +45,7 @@ namespace clang { class InMessageExpressionRAIIObject; class PoisonSEHIdentifiersRAIIObject; class VersionTuple; + class OMPClause; /// Parser - This implements a parser for the C family of languages. After /// parsing units of the grammar, productions are invoked to handle whatever has @@ -101,15 +102,17 @@ class Parser : public CodeCompletionHandler { /// Contextual keywords for Microsoft extensions. IdentifierInfo *Ident__except; + mutable IdentifierInfo *Ident_sealed; /// Ident_super - IdentifierInfo for "super", to support fast /// comparison. IdentifierInfo *Ident_super; - /// Ident_vector and Ident_pixel - cached IdentifierInfo's for - /// "vector" and "pixel" fast comparison. Only present if - /// AltiVec enabled. + /// Ident_vector, Ident_pixel, Ident_bool - cached IdentifierInfo's + /// for "vector", "pixel", and "bool" fast comparison. Only present + /// if AltiVec enabled. IdentifierInfo *Ident_vector; IdentifierInfo *Ident_pixel; + IdentifierInfo *Ident_bool; /// Objective-C contextual keywords. mutable IdentifierInfo *Ident_instancetype; @@ -150,6 +153,7 @@ class Parser : public CodeCompletionHandler { OwningPtr<CommentHandler> CommentSemaHandler; OwningPtr<PragmaHandler> OpenMPHandler; OwningPtr<PragmaHandler> MSCommentHandler; + OwningPtr<PragmaHandler> MSDetectMismatchHandler; /// Whether the '>' token acts as an operator or not. This will be /// true except when we are parsing an expression within a C++ @@ -398,7 +402,8 @@ private: /// \brief Abruptly cut off parsing; mainly used when we have reached the /// code-completion point. void cutOffParsing() { - PP.setCodeCompletionReached(); + if (PP.isCodeCompletionEnabled()) + PP.setCodeCompletionReached(); // Cut off parsing by acting as if we reached the end-of-file. Tok.setKind(tok::eof); } @@ -419,6 +424,10 @@ private: void HandlePragmaMSStruct(); /// \brief Handle the annotation token produced for + /// #pragma comment... + void HandlePragmaMSComment(); + + /// \brief Handle the annotation token produced for /// #pragma align... void HandlePragmaAlign(); @@ -525,7 +534,8 @@ private: bool &isInvalid) { if (!getLangOpts().AltiVec || (Tok.getIdentifierInfo() != Ident_vector && - Tok.getIdentifierInfo() != Ident_pixel)) + Tok.getIdentifierInfo() != Ident_pixel && + Tok.getIdentifierInfo() != Ident_bool)) return false; return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid); @@ -545,6 +555,13 @@ private: const char *&PrevSpec, unsigned &DiagID, bool &isInvalid); + /// TryKeywordIdentFallback - For compatibility with system headers using + /// keywords as identifiers, attempt to convert the current token to an + /// identifier and optionally disable the keyword for the remainder of the + /// translation unit. This returns false if the token was not replaced, + /// otherwise emits a diagnostic and returns true. + bool TryKeywordIdentFallback(bool DisableKeyword); + /// \brief Get the TemplateIdAnnotation from the token. TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok); @@ -599,6 +616,7 @@ private: assert(!isActive && "Forgot to call Commit or Revert!"); } }; + class UnannotatedTentativeParsingAction; /// ObjCDeclContextSwitch - An object used to switch context from /// an objective-c decl context to its enclosing decl context and @@ -725,32 +743,45 @@ private: void CheckNestedObjCContexts(SourceLocation AtLoc); public: + + /// \brief Control flags for SkipUntil functions. + enum SkipUntilFlags { + StopAtSemi = 1 << 0, ///< Stop skipping at semicolon + /// \brief Stop skipping at specified token, but don't skip the token itself + StopBeforeMatch = 1 << 1, + StopAtCodeCompletion = 1 << 2 ///< Stop at code completion + }; + + friend LLVM_CONSTEXPR SkipUntilFlags operator|(SkipUntilFlags L, + SkipUntilFlags R) { + return static_cast<SkipUntilFlags>(static_cast<unsigned>(L) | + static_cast<unsigned>(R)); + } + /// 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 - /// good stopping point. If StopAtSemi is true, skipping will stop at a ';' - /// character. + /// it (unless StopBeforeMatch is specified). Because we cannot guarantee + /// that the token will ever occur, this skips to the next token, or to some + /// likely good stopping point. If Flags has StopAtSemi flag, skipping will + /// stop at a ';' character. /// /// If SkipUntil finds the specified token, it returns true, otherwise it /// returns false. - bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true, - bool DontConsume = false, bool StopAtCodeCompletion = false) { - return SkipUntil(llvm::makeArrayRef(T), StopAtSemi, DontConsume, - StopAtCodeCompletion); + bool SkipUntil(tok::TokenKind T, + SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) { + return SkipUntil(llvm::makeArrayRef(T), Flags); } - bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true, - bool DontConsume = false, bool StopAtCodeCompletion = false) { + bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, + SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) { tok::TokenKind TokArray[] = {T1, T2}; - return SkipUntil(TokArray, StopAtSemi, DontConsume,StopAtCodeCompletion); + return SkipUntil(TokArray, Flags); } bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3, - bool StopAtSemi = true, bool DontConsume = false, - bool StopAtCodeCompletion = false) { + SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) { tok::TokenKind TokArray[] = {T1, T2, T3}; - return SkipUntil(TokArray, StopAtSemi, DontConsume,StopAtCodeCompletion); + return SkipUntil(TokArray, Flags); } - bool SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi = true, - bool DontConsume = false, bool StopAtCodeCompletion = false); + bool SkipUntil(ArrayRef<tok::TokenKind> Toks, + SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)); /// SkipMalformedDecl - Read tokens until we get to some likely good stopping /// point for skipping past a simple-declaration. @@ -1042,32 +1073,21 @@ private: SourceRange getSourceRange() const LLVM_READONLY; }; - /// \brief Contains a late templated function. - /// Will be parsed at the end of the translation unit. - struct LateParsedTemplatedFunction { - explicit LateParsedTemplatedFunction(Decl *MD) - : D(MD) {} - - CachedTokens Toks; - - /// \brief The template function declaration to be late parsed. - Decl *D; - }; - void LexTemplateFunctionForLateParsing(CachedTokens &Toks); - void ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT); - typedef llvm::DenseMap<const FunctionDecl*, LateParsedTemplatedFunction*> - LateParsedTemplateMapT; - LateParsedTemplateMapT LateParsedTemplateMap; + void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT); - static void LateTemplateParserCallback(void *P, const FunctionDecl *FD); - void LateTemplateParser(const FunctionDecl *FD); + static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT); Sema::ParsingClassState PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface); void DeallocateParsedClasses(ParsingClass *Class); void PopParsingClass(Sema::ParsingClassState); + enum CachedInitKind { + CIK_DefaultArgument, + CIK_DefaultInitializer + }; + NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS, AttributeList *AccessAttrs, ParsingDeclarator &D, @@ -1089,6 +1109,8 @@ private: void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI); void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod); bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks); + bool ConsumeAndStoreInitializer(CachedTokens &Toks, CachedInitKind CIK); + bool ConsumeAndStoreConditional(CachedTokens &Toks); bool ConsumeAndStoreUntil(tok::TokenKind T1, CachedTokens &Toks, bool StopAtSemi = true, @@ -1274,6 +1296,12 @@ private: ArrayRef<Expr *> Args) = 0, Expr *Data = 0); + /// ParseSimpleExpressionList - A simple comma-separated list of expressions, + /// used for misc language extensions. + bool ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs, + SmallVectorImpl<SourceLocation> &CommaLocs); + + /// ParenParseOption - Control what ParseParenExpression will parse. enum ParenParseOption { SimpleExpr, // Only parse '(' expression ')' @@ -1325,7 +1353,8 @@ private: // [...] () -> type {...} ExprResult ParseLambdaExpression(); ExprResult TryParseLambdaExpression(); - Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro); + Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro, + bool *SkippedInits = 0); bool TryParseLambdaIntroducer(LambdaIntroducer &Intro); ExprResult ParseLambdaExpressionAfterIntroducer( LambdaIntroducer &Intro); @@ -1461,10 +1490,7 @@ private: /// A SmallVector of types. typedef SmallVector<ParsedType, 12> TypeVector; - StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0) { - StmtVector Stmts; - return ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc); - } + StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0); StmtResult ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement, SourceLocation *TrailingElseLoc = 0); @@ -1628,6 +1654,9 @@ private: AccessSpecifier AS = AS_none, DeclSpecContext DSC = DSC_normal, LateParsedAttrList *LateAttrs = 0); + bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS, + DeclSpecContext DSContext, + LateParsedAttrList *LateAttrs = 0); void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none, DeclSpecContext DSC = DSC_normal); @@ -1800,6 +1829,11 @@ private: isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False(), bool *HasMissingTypename = 0); + /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or + /// \c TPResult::Ambiguous, determine whether the decl-specifier would be + /// a type-specifier other than a cv-qualifier. + bool isCXXDeclarationSpecifierAType(); + /// \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. @@ -1812,15 +1846,18 @@ private: // that more tentative parsing is necessary for disambiguation. // They all consume tokens, so backtracking should be used after calling them. - TPResult TryParseDeclarationSpecifier(bool *HasMissingTypename = 0); TPResult TryParseSimpleDeclaration(bool AllowForRangeDecl); TPResult TryParseTypeofSpecifier(); TPResult TryParseProtocolQualifiers(); + TPResult TryParsePtrOperatorSeq(); + TPResult TryParseOperatorId(); TPResult TryParseInitDeclaratorList(); TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true); - TPResult TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = 0); + TPResult TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = 0, + bool VersusTemplateArg = false); TPResult TryParseFunctionDeclarator(); TPResult TryParseBracketDeclarator(); + TPResult TryConsumeDeclarationSpecifier(); public: TypeResult ParseTypeName(SourceRange *Range = 0, @@ -1866,6 +1903,10 @@ private: // for example, attributes appertain to decl specifiers. void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs); + /// \brief Diagnose and skip C++11 attributes that appear in syntactic + /// locations where attributes are not allowed. + void DiagnoseAndSkipCXX11Attributes(); + void MaybeParseGNUAttributes(Declarator &D, LateParsedAttrList *LateAttrs = 0) { if (Tok.is(tok::kw___attribute)) { @@ -1891,6 +1932,7 @@ private: IdentifierInfo *ScopeName, SourceLocation ScopeLoc, AttributeList::Syntax Syntax); + IdentifierLoc *ParseIdentifierLoc(); void MaybeParseCXX11Attributes(Declarator &D) { if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { @@ -1961,6 +2003,11 @@ private: ParsedAttributes &Attrs, SourceLocation *EndLoc); + void ParseAttributeWithTypeArg(IdentifierInfo &AttrName, + SourceLocation AttrNameLoc, + ParsedAttributes &Attrs, + SourceLocation *EndLoc); + void ParseTypeofSpecifier(DeclSpec &DS); SourceLocation ParseDecltypeSpecifier(DeclSpec &DS); void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS, @@ -2024,7 +2071,8 @@ private: void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true, bool CXX11AttributesAllowed = true, - bool AtomicAllowed = true); + bool AtomicAllowed = true, + bool IdentifierRequired = false); void ParseDirectDeclarator(Declarator &D); void ParseParenDeclarator(Declarator &D); void ParseFunctionDeclarator(Declarator &D, @@ -2035,11 +2083,11 @@ private: bool isFunctionDeclaratorIdentifierList(); void ParseFunctionDeclaratorIdentifierList( Declarator &D, - SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo); + SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo); void ParseParameterDeclarationClause( Declarator &D, ParsedAttributes &attrs, - SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo, + SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo, SourceLocation &EllipsisLoc); void ParseBracketDeclarator(Declarator &D); @@ -2060,6 +2108,8 @@ private: isCXX11AttributeSpecifier(bool Disambiguate = false, bool OuterMightBeMessageSend = false); + void DiagnoseUnexpectedNamespace(NamedDecl *Context); + Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd, SourceLocation InlineLoc = SourceLocation()); void ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc, @@ -2134,9 +2184,44 @@ private: //===--------------------------------------------------------------------===// // OpenMP: Directives and clauses. + /// \brief Parses declarative OpenMP directives. DeclGroupPtrTy ParseOpenMPDeclarativeDirective(); + /// \brief Parses simple list of variables. + /// + /// \param Kind Kind of the directive. + /// \param [out] VarList List of referenced variables. + /// \param AllowScopeSpecifier true, if the variables can have fully + /// qualified names. + /// bool ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, - SmallVectorImpl<DeclarationNameInfo> &IdList); + SmallVectorImpl<Expr *> &VarList, + bool AllowScopeSpecifier); + /// \brief Parses declarative or executable directive. + StmtResult ParseOpenMPDeclarativeOrExecutableDirective(); + /// \brief Parses clause of kind \a CKind for directive of a kind \a Kind. + /// + /// \param DKind Kind of current directive. + /// \param CKind Kind of current clause. + /// \param FirstClause true, if this is the first clause of a kind \a CKind + /// in current directive. + /// + OMPClause *ParseOpenMPClause(OpenMPDirectiveKind DKind, + OpenMPClauseKind CKind, bool FirstClause); + /// \brief Parses clause with a single expression of a kind \a Kind. + /// + /// \param Kind Kind of current clause. + /// + OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind); + /// \brief Parses simple clause of a kind \a Kind. + /// + /// \param Kind Kind of current clause. + /// + OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind); + /// \brief Parses clause with the list of variables of a kind \a Kind. + /// + /// \param Kind Kind of current clause. + /// + OMPClause *ParseOpenMPVarListClause(OpenMPClauseKind Kind); public: bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/Core/HTMLRewrite.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/HTMLRewrite.h index 88caf85..3cd0461 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/Core/HTMLRewrite.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/HTMLRewrite.h @@ -57,7 +57,7 @@ namespace html { /// in 's' are not interpreted as HTML tags. Unlike the version of /// EscapeText that rewrites a file, this version by default replaces tabs /// with spaces. - std::string EscapeText(const std::string& s, + std::string EscapeText(StringRef s, bool EscapeSpaces = false, bool ReplaceTabs = false); void AddLineNumbers(Rewriter& R, FileID FID); diff --git a/contrib/llvm/tools/clang/include/clang/Rewrite/Core/Rewriter.h b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/Rewriter.h index cb044ae..2d2917b 100644 --- a/contrib/llvm/tools/clang/include/clang/Rewrite/Core/Rewriter.h +++ b/contrib/llvm/tools/clang/include/clang/Rewrite/Core/Rewriter.h @@ -40,20 +40,18 @@ class RewriteBuffer { /// Deltas - Keep track of all the deltas in the source code due to insertions /// and deletions. DeltaTree Deltas; - - /// Buffer - This is the actual buffer itself. Note that using a vector or - /// string is a horribly inefficient way to do this, we should use a rope - /// instead. - typedef RewriteRope BufferTy; - BufferTy Buffer; + RewriteRope Buffer; public: - typedef BufferTy::const_iterator iterator; + typedef RewriteRope::const_iterator iterator; iterator begin() const { return Buffer.begin(); } iterator end() const { return Buffer.end(); } unsigned size() const { return Buffer.size(); } /// \brief Write to \p Stream the result of applying all changes to the /// original buffer. + /// Note that it isn't safe to use this function to overwrite memory mapped + /// files in-place (PR17960). Consider using a higher-level utility such as + /// Rewriter::overwriteChangedFiles() instead. /// /// The original buffer is not actually changed. raw_ostream &write(raw_ostream &Stream) const; @@ -149,6 +147,7 @@ public: }; typedef std::map<FileID, RewriteBuffer>::iterator buffer_iterator; + typedef std::map<FileID, RewriteBuffer>::const_iterator const_buffer_iterator; explicit Rewriter(SourceManager &SM, const LangOptions &LO) : SourceMgr(&SM), LangOpts(&LO) {} @@ -282,10 +281,12 @@ public: // Iterators over rewrite buffers. buffer_iterator buffer_begin() { return RewriteBuffers.begin(); } buffer_iterator buffer_end() { return RewriteBuffers.end(); } + const_buffer_iterator buffer_begin() const { return RewriteBuffers.begin(); } + const_buffer_iterator buffer_end() const { return RewriteBuffers.end(); } /// overwriteChangedFiles - Save all changed files to disk. /// - /// Returns whether not all changes were saved successfully. + /// Returns true if any files were not saved successfully. /// Outputs diagnostics via the source manager's diagnostic engine /// in case of an error. bool overwriteChangedFiles(); diff --git a/contrib/llvm/tools/clang/include/clang/Sema/AnalysisBasedWarnings.h b/contrib/llvm/tools/clang/include/clang/Sema/AnalysisBasedWarnings.h index eeac973..432c4e2 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/AnalysisBasedWarnings.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/AnalysisBasedWarnings.h @@ -38,6 +38,7 @@ public: unsigned enableCheckFallThrough : 1; unsigned enableCheckUnreachable : 1; unsigned enableThreadSafetyAnalysis : 1; + unsigned enableConsumedAnalysis : 1; public: Policy(); void disableCheckFallThrough() { enableCheckFallThrough = 0; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h b/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h index d5f3177..508064d 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h @@ -19,6 +19,7 @@ #include "clang/Basic/VersionTuple.h" #include "clang/Sema/Ownership.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Allocator.h" #include <cassert> @@ -44,6 +45,20 @@ struct AvailabilityChange { bool isValid() const { return !Version.empty(); } }; +/// \brief Wraps an identifier and optional source location for the identifier. +struct IdentifierLoc { + SourceLocation Loc; + IdentifierInfo *Ident; + + static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc, + IdentifierInfo *Ident); +}; + +/// \brief A union of the various pointer types that can be passed to an +/// AttributeList as an argument. +typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion; +typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector; + /// AttributeList - Represents a syntactic attribute. /// /// For a GNU attribute, there are four forms of this construct: @@ -66,13 +81,12 @@ public: /// __ptr16, alignas(...), etc. AS_Keyword }; + private: IdentifierInfo *AttrName; IdentifierInfo *ScopeName; - IdentifierInfo *ParmName; SourceRange AttrRange; SourceLocation ScopeLoc; - SourceLocation ParmLoc; SourceLocation EllipsisLoc; /// The number of expression arguments this attribute has. @@ -100,6 +114,9 @@ private: /// Microsoft __delcspec(property) attribute. unsigned IsProperty : 1; + /// True if this has a ParsedType + unsigned HasParsedType : 1; + unsigned AttrKind : 8; /// \brief The location of the 'unavailable' keyword in an @@ -114,22 +131,27 @@ private: /// The next attribute allocated in the current Pool. AttributeList *NextInPool; - Expr **getArgsBuffer() { - return reinterpret_cast<Expr**>(this+1); + /// Arguments, if any, are stored immediately following the object. + ArgsUnion *getArgsBuffer() { + return reinterpret_cast<ArgsUnion*>(this+1); } - Expr * const *getArgsBuffer() const { - return reinterpret_cast<Expr* const *>(this+1); + ArgsUnion const *getArgsBuffer() const { + return reinterpret_cast<ArgsUnion const *>(this+1); } enum AvailabilitySlot { IntroducedSlot, DeprecatedSlot, ObsoletedSlot }; - AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { - return reinterpret_cast<AvailabilityChange*>(this+1)[index]; + /// Availability information is stored immediately following the arguments, + /// if any, at the end of the object. + AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { + return reinterpret_cast<AvailabilityChange*>(getArgsBuffer() + + NumArgs)[index]; } const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const { - return reinterpret_cast<const AvailabilityChange*>(this+1)[index]; + return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer() + + NumArgs)[index]; } public: @@ -145,14 +167,20 @@ public: }; private: + /// Type tag information is stored immediately following the arguments, if + /// any, at the end of the object. They are mutually exlusive with + /// availability slots. TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() { - return *reinterpret_cast<TypeTagForDatatypeData *>(this + 1); + return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs); } const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const { - return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1); + return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer() + + NumArgs); } + /// The type buffer immediately follows the object and are mutually exclusive + /// with arguments. ParsedType &getTypeBuffer() { return *reinterpret_cast<ParsedType *>(this + 1); } @@ -161,6 +189,8 @@ private: return *reinterpret_cast<const ParsedType *>(this + 1); } + /// The property data immediately follows the object is is mutually exclusive + /// with arguments. PropertyData &getPropertyDataBuffer() { assert(IsProperty); return *reinterpret_cast<PropertyData*>(this + 1); @@ -181,36 +211,34 @@ private: /// Constructor for attributes with expression arguments. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - Expr **args, unsigned numArgs, + ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed, SourceLocation ellipsisLoc) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed), - Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0), - NextInPool(0) { - if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), + SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), + IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), + HasParsedType(false), NextInPosition(0), NextInPool(0) { + if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } /// Constructor for availability attributes. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - const AvailabilityChange &introduced, + IdentifierLoc *Parm, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *messageExpr, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(), - NumArgs(0), SyntaxUsed(syntaxUsed), + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), - IsTypeTagForDatatype(false), IsProperty(false), + IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), UnavailableLoc(unavailable), MessageExpr(messageExpr), NextInPosition(0), NextInPool(0) { + ArgsUnion PVal(Parm); + memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); @@ -220,16 +248,15 @@ private: /// Constructor for type_tag_for_datatype attribute. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *argumentKindName, - SourceLocation argumentKindLoc, - ParsedType matchingCType, bool layoutCompatible, - bool mustBeNull, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(argumentKindName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc), - EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), + IdentifierLoc *ArgKind, ParsedType matchingCType, + bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed) + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(true), IsProperty(false), NextInPosition(NULL), - NextInPool(NULL) { + IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), + NextInPosition(NULL), NextInPool(NULL) { + ArgsUnion PVal(ArgKind); + memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); new (&ExtraData.MatchingCType) ParsedType(matchingCType); ExtraData.LayoutCompatible = layoutCompatible; @@ -240,14 +267,12 @@ private: /// Constructor for attributes with a single type argument. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, ParsedType typeArg, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), - UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0), - NextInPool(0) { + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), + Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), + IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), + NextInPosition(0), NextInPool(0) { new (&getTypeBuffer()) ParsedType(typeArg); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -255,15 +280,13 @@ private: /// Constructor for microsoft __declspec(property) attribute. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - SyntaxUsed(syntaxUsed), + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(true), NextInPosition(0), - NextInPool(0) { + IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), + NextInPosition(0), NextInPool(0) { new (&getPropertyDataBuffer()) PropertyData(getterId, setterId); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -288,8 +311,7 @@ public: IdentifierInfo *getScopeName() const { return ScopeName; } SourceLocation getScopeLoc() const { return ScopeLoc; } - IdentifierInfo *getParameterName() const { return ParmName; } - SourceLocation getParameterLoc() const { return ParmLoc; } + bool hasParsedType() const { return HasParsedType; } /// Is this the Microsoft __declspec(property) attribute? bool isDeclspecPropertyAttribute() const { @@ -326,21 +348,31 @@ public: /// getNumArgs - Return the number of actual arguments to this attribute. unsigned getNumArgs() const { return NumArgs; } - /// hasParameterOrArguments - Return true if this attribute has a parameter, - /// or has a non empty argument expression list. - bool hasParameterOrArguments() const { return ParmName || NumArgs; } - /// getArg - Return the specified argument. - Expr *getArg(unsigned Arg) const { + ArgsUnion getArg(unsigned Arg) const { assert(Arg < NumArgs && "Arg access out of range!"); return getArgsBuffer()[Arg]; } + bool isArgExpr(unsigned Arg) const { + return Arg < NumArgs && getArg(Arg).is<Expr*>(); + } + Expr *getArgAsExpr(unsigned Arg) const { + return getArg(Arg).get<Expr*>(); + } + + bool isArgIdent(unsigned Arg) const { + return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>(); + } + IdentifierLoc *getArgAsIdent(unsigned Arg) const { + return getArg(Arg).get<IdentifierLoc*>(); + } + class arg_iterator { - Expr * const *X; + ArgsUnion const *X; unsigned Idx; public: - arg_iterator(Expr * const *x, unsigned idx) : X(x), Idx(idx) {} + arg_iterator(ArgsUnion const *x, unsigned idx) : X(x), Idx(idx) {} arg_iterator& operator++() { ++Idx; @@ -357,7 +389,7 @@ public: return !operator==(I); } - Expr* operator*() const { + ArgsUnion operator*() const { return X[Idx]; } @@ -418,7 +450,7 @@ public: } const ParsedType &getTypeArg() const { - assert(getKind() == AT_VecTypeHint && "Not a type attribute"); + assert(HasParsedType && "Not a type attribute"); return getTypeBuffer(); } @@ -431,6 +463,10 @@ public: /// defined in Attr.td. This index is used by an attribute /// to pretty print itself. unsigned getAttributeSpellingListIndex() const; + + bool hasCustomParsing() const; + unsigned getMinArgs() const; + unsigned getMaxArgs() const; }; /// A factory, from which one makes pools, from which one creates @@ -445,11 +481,13 @@ public: /// which we want to ensure is a multiple of sizeof(void*). AvailabilityAllocSize = sizeof(AttributeList) - + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1) + + ((3 * sizeof(AvailabilityChange) + sizeof(void*) + + sizeof(ArgsUnion) - 1) / sizeof(void*) * sizeof(void*)), TypeTagForDatatypeAllocSize = sizeof(AttributeList) - + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) - 1) + + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) + + sizeof(ArgsUnion) - 1) / sizeof(void*) * sizeof(void*), PropertyAllocSize = sizeof(AttributeList) @@ -541,22 +579,20 @@ public: AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - Expr **args, unsigned numArgs, + ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc = SourceLocation()) { void *memory = allocate(sizeof(AttributeList) - + numArgs * sizeof(Expr*)); + + numArgs * sizeof(ArgsUnion)); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, args, numArgs, syntax, ellipsisLoc)); } AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, + IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, @@ -566,9 +602,9 @@ public: void *memory = allocate(AttributeFactory::AvailabilityAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, - introduced, deprecated, obsoleted, - unavailable, MessageExpr, syntax)); + Param, introduced, deprecated, + obsoleted, unavailable, MessageExpr, + syntax)); } AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name, @@ -577,40 +613,35 @@ public: AttributeList *createTypeTagForDatatype( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *argumentKindName, - SourceLocation argumentKindLoc, - ParsedType matchingCType, bool layoutCompatible, - bool mustBeNull, AttributeList::Syntax syntax) { + IdentifierLoc *argumentKind, ParsedType matchingCType, + bool layoutCompatible, bool mustBeNull, + AttributeList::Syntax syntax) { void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - argumentKindName, argumentKindLoc, - matchingCType, layoutCompatible, - mustBeNull, syntax)); + argumentKind, matchingCType, + layoutCompatible, mustBeNull, + syntax)); } AttributeList *createTypeAttribute( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, ParsedType typeArg, AttributeList::Syntax syntaxUsed) { void *memory = allocate(sizeof(AttributeList) + sizeof(void *)); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, typeArg, syntaxUsed)); } AttributeList *createPropertyAttribute( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed) { void *memory = allocate(AttributeFactory::PropertyAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, getterId, setterId, syntaxUsed)); } @@ -709,13 +740,12 @@ public: /// Add attribute with expression arguments. AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - Expr **args, unsigned numArgs, + ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc = SourceLocation()) { AttributeList *attr = - pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - args, numArgs, syntax, ellipsisLoc); + pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs, + syntax, ellipsisLoc); add(attr); return attr; } @@ -723,7 +753,7 @@ public: /// Add availability attribute. AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, + IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, @@ -731,9 +761,8 @@ public: const Expr *MessageExpr, AttributeList::Syntax syntax) { AttributeList *attr = - pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - introduced, deprecated, obsoleted, unavailable, - MessageExpr, syntax); + pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced, + deprecated, obsoleted, unavailable, MessageExpr, syntax); add(attr); return attr; } @@ -742,16 +771,14 @@ public: AttributeList *addNewTypeTagForDatatype( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *argumentKindName, - SourceLocation argumentKindLoc, - ParsedType matchingCType, bool layoutCompatible, - bool mustBeNull, AttributeList::Syntax syntax) { + IdentifierLoc *argumentKind, ParsedType matchingCType, + bool layoutCompatible, bool mustBeNull, + AttributeList::Syntax syntax) { AttributeList *attr = pool.createTypeTagForDatatype(attrName, attrRange, scopeName, scopeLoc, - argumentKindName, argumentKindLoc, - matchingCType, layoutCompatible, - mustBeNull, syntax); + argumentKind, matchingCType, + layoutCompatible, mustBeNull, syntax); add(attr); return attr; } @@ -760,11 +787,10 @@ public: AttributeList * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, ParsedType typeArg, AttributeList::Syntax syntaxUsed) { AttributeList *attr = pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, typeArg, syntaxUsed); + typeArg, syntaxUsed); add(attr); return attr; } @@ -773,13 +799,11 @@ public: AttributeList * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed) { AttributeList *attr = pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, getterId, setterId, - syntaxUsed); + getterId, setterId, syntaxUsed); add(attr); return attr; } @@ -798,6 +822,15 @@ private: AttributeList *list; }; +/// These constants match the enumerated choices of +/// err_attribute_argument_n_type and err_attribute_argument_type. +enum AttributeArgumentNType { + AANT_ArgumentIntOrBool, + AANT_ArgumentIntegerConstant, + AANT_ArgumentString, + AANT_ArgumentIdentifier +}; + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h index a1ddec7..64de82c 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -271,22 +271,17 @@ private: QualType BaseType; /// \brief The identifiers for Objective-C selector parts. - IdentifierInfo **SelIdents; - - /// \brief The number of Objective-C selector parts. - unsigned NumSelIdents; + ArrayRef<IdentifierInfo *> SelIdents; public: /// \brief Construct a new code-completion context of the given kind. - CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(NULL), - NumSelIdents(0) { } + CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(None) { } /// \brief Construct a new code-completion context of the given kind. CodeCompletionContext(enum Kind Kind, QualType T, - IdentifierInfo **SelIdents = NULL, - unsigned NumSelIdents = 0) : Kind(Kind), - SelIdents(SelIdents), - NumSelIdents(NumSelIdents) { + ArrayRef<IdentifierInfo *> SelIdents = None) + : Kind(Kind), + SelIdents(SelIdents) { if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess || Kind == CCC_ObjCPropertyAccess || Kind == CCC_ObjCClassMessage || Kind == CCC_ObjCInstanceMessage) @@ -308,10 +303,7 @@ public: QualType getBaseType() const { return BaseType; } /// \brief Retrieve the Objective-C selector identifiers. - IdentifierInfo **getSelIdents() const { return SelIdents; } - - /// \brief Retrieve the number of Objective-C selector identifiers. - unsigned getNumSelIdents() const { return NumSelIdents; } + ArrayRef<IdentifierInfo *> getSelIdents() const { return SelIdents; } /// \brief Determines whether we want C++ constructors as results within this /// context. diff --git a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h index 059919a..8f6bd18 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h @@ -337,6 +337,7 @@ private: // function-specifier unsigned FS_inline_specified : 1; + unsigned FS_forceinline_specified: 1; unsigned FS_virtual_specified : 1; unsigned FS_explicit_specified : 1; unsigned FS_noreturn_specified : 1; @@ -381,6 +382,7 @@ private: SourceRange TypeofParensRange; SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; + SourceLocation FS_forceinlineLoc; SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc; WrittenBuiltinSpecs writtenBS; @@ -419,6 +421,7 @@ public: TypeSpecOwned(false), TypeQualifiers(TQ_unspecified), FS_inline_specified(false), + FS_forceinline_specified(false), FS_virtual_specified(false), FS_explicit_specified(false), FS_noreturn_specified(false), @@ -458,6 +461,12 @@ public: ThreadStorageClassSpecLoc = SourceLocation(); } + void ClearTypeSpecType() { + TypeSpecType = DeclSpec::TST_unspecified; + TypeSpecOwned = false; + TSTLoc = SourceLocation(); + } + // type-specifier TSW getTypeSpecWidth() const { return (TSW)TypeSpecWidth; } TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; } @@ -504,6 +513,8 @@ public: return TypeSpecType == TST_auto || TypeSpecType == TST_decltype_auto; } + bool hasTagDefinition() const; + /// \brief Turn a type-specifier-type into a string like "_Bool" or "union". static const char *getSpecifierName(DeclSpec::TST T); static const char *getSpecifierName(DeclSpec::TQ Q); @@ -532,8 +543,12 @@ public: } // function-specifier - bool isInlineSpecified() const { return FS_inline_specified; } - SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; } + bool isInlineSpecified() const { + return FS_inline_specified | FS_forceinline_specified; + } + SourceLocation getInlineSpecLoc() const { + return FS_inline_specified ? FS_inlineLoc : FS_forceinlineLoc; + } bool isVirtualSpecified() const { return FS_virtual_specified; } SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; } @@ -547,6 +562,8 @@ public: void ClearFunctionSpecs() { FS_inline_specified = false; FS_inlineLoc = SourceLocation(); + FS_forceinline_specified = false; + FS_forceinlineLoc = SourceLocation(); FS_virtual_specified = false; FS_virtualLoc = SourceLocation(); FS_explicit_specified = false; @@ -615,6 +632,8 @@ public: const char *&PrevSpec, unsigned &DiagID); bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); + bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID); bool SetTypeSpecError(); void UpdateDeclRep(Decl *Rep) { assert(isDeclRep((TST) TypeSpecType)); @@ -632,10 +651,16 @@ public: bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const LangOptions &Lang); - bool setFunctionSpecInline(SourceLocation Loc); - bool setFunctionSpecVirtual(SourceLocation Loc); - bool setFunctionSpecExplicit(SourceLocation Loc); - bool setFunctionSpecNoreturn(SourceLocation Loc); + bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID); + bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID); + bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID); + bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID); + bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID); bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); @@ -1500,6 +1525,7 @@ public: ObjCCatchContext, // Objective-C catch exception-declaration BlockLiteralContext, // Block literal declarator. LambdaExprContext, // Lambda-expression declarator. + LambdaExprParameterContext, // Lambda-expression parameter declarator. ConversionIdContext, // C++ conversion-type-id. TrailingReturnContext, // C++11 trailing-type-specifier. TemplateTypeArgContext, // Template type argument. @@ -1575,7 +1601,6 @@ public: ~Declarator() { clear(); } - /// getDeclSpec - Return the declaration-specifier that this declarator was /// declared with. const DeclSpec &getDeclSpec() const { return DS; } @@ -1604,7 +1629,8 @@ public: bool isPrototypeContext() const { return (Context == PrototypeContext || Context == ObjCParameterContext || - Context == ObjCResultContext); + Context == ObjCResultContext || + Context == LambdaExprParameterContext); } /// \brief Get the source range that spans this declarator. @@ -1668,6 +1694,7 @@ public: case AliasDeclContext: case AliasTemplateContext: case PrototypeContext: + case LambdaExprParameterContext: case ObjCParameterContext: case ObjCResultContext: case TemplateParamContext: @@ -1696,6 +1723,7 @@ public: case ForContext: case ConditionContext: case PrototypeContext: + case LambdaExprParameterContext: case TemplateParamContext: case CXXCatchContext: case ObjCCatchContext: @@ -1717,6 +1745,39 @@ public: llvm_unreachable("unknown context kind!"); } + /// diagnoseIdentifier - Return true if the identifier is prohibited and + /// should be diagnosed (because it cannot be anything else). + bool diagnoseIdentifier() const { + switch (Context) { + case FileContext: + case KNRTypeListContext: + case MemberContext: + case BlockContext: + case ForContext: + case ConditionContext: + case PrototypeContext: + case LambdaExprParameterContext: + case TemplateParamContext: + case CXXCatchContext: + case ObjCCatchContext: + case TypeNameContext: + case ConversionIdContext: + case ObjCParameterContext: + case ObjCResultContext: + case BlockLiteralContext: + case CXXNewContext: + case LambdaExprContext: + return false; + + case AliasDeclContext: + case AliasTemplateContext: + case TemplateTypeArgContext: + case TrailingReturnContext: + return true; + } + llvm_unreachable("unknown context kind!"); + } + /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be /// followed by a C++ direct initializer, e.g. "int x(1);". bool mayBeFollowedByCXXDirectInit() const { @@ -1748,6 +1809,7 @@ public: case KNRTypeListContext: case MemberContext: case PrototypeContext: + case LambdaExprParameterContext: case ObjCParameterContext: case ObjCResultContext: case TemplateParamContext: @@ -1934,6 +1996,7 @@ public: case AliasDeclContext: case AliasTemplateContext: case PrototypeContext: + case LambdaExprParameterContext: case ObjCParameterContext: case ObjCResultContext: case TemplateParamContext: @@ -1995,7 +2058,7 @@ public: /// \brief Return a source range list of C++11 attributes associated /// with the declarator. - void getCXX11AttributeRanges(SmallVector<SourceRange, 4> &Ranges) { + void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) { AttributeList *AttrList = Attrs.getList(); while (AttrList) { if (AttrList->isCXX11Attribute()) @@ -2038,6 +2101,16 @@ public: return (FunctionDefinitionKind)FunctionDefinition; } + /// Returns true if this declares a real member and not a friend. + bool isFirstDeclarationOfMember() { + return getContext() == MemberContext && !getDeclSpec().isFriendSpecified(); + } + + /// Returns true if this declares a static member. This cannot be called on a + /// declarator outside of a MemberContext because we won't know until + /// redeclaration time if the decl is static. + bool isStaticMember(); + void setRedeclaration(bool Val) { Redeclaration = Val; } bool isRedeclaration() const { return Redeclaration; } }; @@ -2057,7 +2130,8 @@ public: enum Specifier { VS_None = 0, VS_Override = 1, - VS_Final = 2 + VS_Final = 2, + VS_Sealed = 4 }; VirtSpecifiers() : Specifiers(0) { } @@ -2068,7 +2142,8 @@ public: bool isOverrideSpecified() const { return Specifiers & VS_Override; } SourceLocation getOverrideLoc() const { return VS_overrideLoc; } - bool isFinalSpecified() const { return Specifiers & VS_Final; } + bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed); } + bool isFinalSpelledSealed() const { return Specifiers & VS_Sealed; } SourceLocation getFinalLoc() const { return VS_finalLoc; } void clear() { Specifiers = 0; } @@ -2088,13 +2163,16 @@ private: struct LambdaCapture { LambdaCaptureKind Kind; SourceLocation Loc; - IdentifierInfo* Id; + IdentifierInfo *Id; SourceLocation EllipsisLoc; - + ExprResult Init; + ParsedType InitCaptureType; LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc, - IdentifierInfo* Id = 0, - SourceLocation EllipsisLoc = SourceLocation()) - : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc) + IdentifierInfo* Id, + SourceLocation EllipsisLoc, + ExprResult Init, ParsedType InitCaptureType) + : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init), + InitCaptureType(InitCaptureType) {} }; @@ -2111,11 +2189,13 @@ struct LambdaIntroducer { /// \brief Append a capture in a lambda introducer. void addCapture(LambdaCaptureKind Kind, SourceLocation Loc, - IdentifierInfo* Id = 0, - SourceLocation EllipsisLoc = SourceLocation()) { - Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc)); + IdentifierInfo* Id, + SourceLocation EllipsisLoc, + ExprResult Init, + ParsedType InitCaptureType) { + Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, Init, + InitCaptureType)); } - }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h index 3704e09..4f4a87f 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/DelayedDiagnostic.h @@ -6,16 +6,17 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the DelayedDiagnostic class, which is used to -// record diagnostics that are being conditionally produced during -// declarator parsing. Certain kinds of diagnostics --- notably -// deprecation and access control --- are suppressed based on -// semantic properties of the parsed declaration that aren't known -// until it is fully parsed. -// -// This file also defines AccessedEntity. -// +/// +/// \file +/// \brief Defines the classes clang::DelayedDiagnostic and +/// clang::AccessedEntity. +/// +/// DelayedDiangostic is used to record diagnostics that are being +/// conditionally produced during declarator parsing. Certain kinds of +/// diagnostics -- notably deprecation and access control -- are suppressed +/// based on semantic properties of the parsed declaration that aren't known +/// until it is fully parsed. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H @@ -224,8 +225,7 @@ private: }; }; -/// DelayedDiagnosticPool - A collection of diagnostics which were -/// delayed. +/// \brief A collection of diagnostics which were delayed. class DelayedDiagnosticPool { const DelayedDiagnosticPool *Parent; SmallVector<DelayedDiagnostic, 4> Diagnostics; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h index cbce757..325abdf 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h @@ -14,6 +14,8 @@ #define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/Type.h" +#include "clang/Sema/TypoCorrection.h" #include "clang/Sema/Weak.h" #include "llvm/ADT/MapVector.h" #include <utility> @@ -30,7 +32,8 @@ class Sema; class TypedefNameDecl; class ValueDecl; class VarDecl; - +struct LateParsedTemplate; + /// \brief A simple structure that captures a vtable use for the purposes of /// the \c ExternalSemaSource. struct ExternalVTableUse { @@ -177,6 +180,45 @@ public: SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending) {} + /// \brief Read the set of late parsed template functions for this source. + /// + /// The external source should insert its own late parsed template functions + /// into the map. Note that this routine may be invoked multiple times; the + /// external source should take care not to introduce the same map entries + /// repeatedly. + virtual void ReadLateParsedTemplates( + llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {} + + /// \copydoc Sema::CorrectTypo + /// \note LookupKind must correspond to a valid Sema::LookupNameKind + /// + /// ExternalSemaSource::CorrectTypo is always given the first chance to + /// correct a typo (really, to offer suggestions to repair a failed lookup). + /// It will even be called when SpellChecking is turned off or after a + /// fatal error has already been detected. + virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, + int LookupKind, Scope *S, CXXScopeSpec *SS, + CorrectionCandidateCallback &CCC, + DeclContext *MemberContext, + bool EnteringContext, + const ObjCObjectPointerType *OPT) { + return TypoCorrection(); + } + + /// \brief Produces a diagnostic note if the external source contains a + /// complete definition for \p T. + /// + /// \param Loc the location at which a complete type was required but not + /// provided + /// + /// \param T the \c QualType that should have been complete at \p Loc + /// + /// \return true if a diagnostic was produced, false otherwise. + virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc, + QualType T) { + return false; + } + // isa/cast/dyn_cast support static bool classof(const ExternalASTSource *Source) { return Source->SemaSource; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/IdentifierResolver.h b/contrib/llvm/tools/clang/include/clang/Sema/IdentifierResolver.h index 0b1b74a..99d94a1 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/IdentifierResolver.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/IdentifierResolver.h @@ -51,11 +51,6 @@ class IdentifierResolver { /// The decl must already be part of the decl chain. void RemoveDecl(NamedDecl *D); - /// Replaces the Old declaration with the New declaration. If the - /// replacement is successful, returns true. If the old - /// declaration was not found, returns false. - bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); - /// \brief Insert the given declaration at the given position in the list. void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) { Decls.insert(Pos, D); @@ -168,11 +163,6 @@ public: /// The decl must already be part of the decl chain. void RemoveDecl(NamedDecl *D); - /// Replace the decl Old with the new declaration New on its - /// identifier chain. Returns true if the old declaration was found - /// (and, therefore, replaced). - bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); - /// \brief Insert the given declaration after the given iterator /// position. void InsertDeclAfter(iterator Pos, NamedDecl *D); diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h b/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h index 58781ac..83fb2be 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h @@ -35,6 +35,7 @@ class ParmVarDecl; class Sema; class TypeLoc; class VarDecl; +class ObjCMethodDecl; /// \brief Describes an entity that is being initialized. class InitializedEntity { @@ -78,7 +79,17 @@ public: EK_LambdaCapture, /// \brief The entity being initialized is the initializer for a compound /// literal. - EK_CompoundLiteralInit + EK_CompoundLiteralInit, + /// \brief The entity being implicitly initialized back to the formal + /// result type. + EK_RelatedResult, + /// \brief The entity being initialized is a function parameter; function + /// is member of group of audited CF APIs. + EK_Parameter_CF_Audited + + // Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this + // enum as an index for its first %select. When modifying this list, + // that diagnostic text needs to be updated as well. }; private: @@ -105,8 +116,8 @@ private: }; struct C { - /// \brief The variable being captured by an EK_LambdaCapture. - VarDecl *Var; + /// \brief The name of the variable being captured by an EK_LambdaCapture. + IdentifierInfo *VarID; /// \brief The source location at which the capture occurs. unsigned Location; @@ -116,6 +127,10 @@ private: /// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or /// FieldDecl, respectively. DeclaratorDecl *VariableOrMember; + + /// \brief When Kind == EK_RelatedResult, the ObjectiveC method where + /// result type was implicitly changed to accommodate ARC semantics. + ObjCMethodDecl *MethodDecl; /// \brief When Kind == EK_Parameter, the ParmVarDecl, with the /// low bit indicating whether the parameter is "consumed". @@ -168,10 +183,10 @@ private: const InitializedEntity &Parent); /// \brief Create the initialization entity for a lambda capture. - InitializedEntity(VarDecl *Var, FieldDecl *Field, SourceLocation Loc) - : Kind(EK_LambdaCapture), Parent(0), Type(Field->getType()) + InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc) + : Kind(EK_LambdaCapture), Parent(0), Type(FieldType) { - Capture.Var = Var; + Capture.VarID = VarID; Capture.Location = Loc.getRawEncoding(); } @@ -254,10 +269,19 @@ public: Result.TypeInfo = TypeInfo; return Result; } + + /// \brief Create the initialization entity for a related result. + static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD, + QualType Type) { + InitializedEntity Result(EK_RelatedResult, SourceLocation(), Type); + Result.MethodDecl = MD; + return Result; + } + /// \brief Create the initialization entity for a base class subobject. static InitializedEntity InitializeBase(ASTContext &Context, - CXXBaseSpecifier *Base, + const CXXBaseSpecifier *Base, bool IsInheritedVirtualBase); /// \brief Create the initialization entity for a delegated constructor. @@ -285,10 +309,10 @@ public: } /// \brief Create the initialization entity for a lambda capture. - static InitializedEntity InitializeLambdaCapture(VarDecl *Var, - FieldDecl *Field, + static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID, + QualType FieldType, SourceLocation Loc) { - return InitializedEntity(Var, Field, Loc); + return InitializedEntity(VarID, FieldType, Loc); } /// \brief Create the entity for a compound literal initializer. @@ -326,22 +350,29 @@ public: /// \brief Retrieve the variable, parameter, or field being /// initialized. DeclaratorDecl *getDecl() const; + + /// \brief Retrieve the ObjectiveC method being initialized. + ObjCMethodDecl *getMethodDecl() const { return MethodDecl; } /// \brief Determine whether this initialization allows the named return /// value optimization, which also applies to thrown objects. bool allowsNRVO() const; + bool isParameterKind() const { + return (getKind() == EK_Parameter || + getKind() == EK_Parameter_CF_Audited); + } /// \brief Determine whether this initialization consumes the /// parameter. bool isParameterConsumed() const { - assert(getKind() == EK_Parameter && "Not a parameter"); + assert(isParameterKind() && "Not a parameter"); return (Parameter & 1); } /// \brief Retrieve the base specifier. - CXXBaseSpecifier *getBaseSpecifier() const { + const CXXBaseSpecifier *getBaseSpecifier() const { assert(getKind() == EK_Base && "Not a base specifier"); - return reinterpret_cast<CXXBaseSpecifier *>(Base & ~0x1); + return reinterpret_cast<const CXXBaseSpecifier *>(Base & ~0x1); } /// \brief Return whether the base is an inherited virtual base. @@ -371,19 +402,28 @@ public: getKind() == EK_ComplexElement); this->Index = Index; } - - /// \brief Retrieve the variable for a captured variable in a lambda. - VarDecl *getCapturedVar() const { + /// \brief For a lambda capture, return the capture's name. + StringRef getCapturedVarName() const { assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); - return Capture.Var; + return Capture.VarID->getName(); } - /// \brief Determine the location of the capture when initializing /// field from a captured variable in a lambda. SourceLocation getCaptureLoc() const { assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); return SourceLocation::getFromRawEncoding(Capture.Location); } + + void setParameterCFAudited() { + Kind = EK_Parameter_CF_Audited; + } + + /// Dump a representation of the initialized entity to standard error, + /// for debugging purposes. + void dump() const; + +private: + unsigned dumpImpl(raw_ostream &OS) const; }; /// \brief Describes the kind of initialization being performed, along with @@ -544,8 +584,10 @@ public: bool AllowExplicit() const { return !isCopyInit(); } /// \brief Retrieve whether this initialization allows the use of explicit - /// conversion functions. - bool allowExplicitConversionFunctions() const { + /// conversion functions when binding a reference. If the reference is the + /// first parameter in a copy or move constructor, such conversions are + /// permitted even though we are performing copy-initialization. + bool allowExplicitConversionFunctionsInRefBinding() const { return !isCopyInit() || Context == IC_ExplicitConvs; } @@ -610,6 +652,8 @@ public: SK_LValueToRValue, /// \brief Perform an implicit conversion sequence. SK_ConversionSequence, + /// \brief Perform an implicit conversion sequence without narrowing. + SK_ConversionSequenceNoNarrowing, /// \brief Perform list-initialization without a constructor SK_ListInitialization, /// \brief Perform list-initialization with a constructor. @@ -706,6 +750,16 @@ public: /// \brief Array must be initialized with an initializer list or a /// string literal. FK_ArrayNeedsInitListOrStringLiteral, + /// \brief Array must be initialized with an initializer list or a + /// wide string literal. + FK_ArrayNeedsInitListOrWideStringLiteral, + /// \brief Initializing a wide char array with narrow string literal. + FK_NarrowStringIntoWideCharArray, + /// \brief Initializing char array with wide string literal. + FK_WideStringIntoCharArray, + /// \brief Initializing wide char array with incompatible wide string + /// literal. + FK_IncompatWideStringIntoWideChar, /// \brief Array type mismatch. FK_ArrayTypeMismatch, /// \brief Non-constant array initializer @@ -753,9 +807,6 @@ public: /// \brief Initializer has a placeholder type which cannot be /// resolved by initialization. FK_PlaceholderType, - /// \brief Failed to initialize a std::initializer_list because copy - /// construction of some element failed. - FK_InitListElementCopyFailure, /// \brief List-copy-initialization chose an explicit constructor. FK_ExplicitConstructor }; @@ -791,11 +842,19 @@ public: /// \param Kind the kind of initialization being performed. /// /// \param Args the argument(s) provided for initialization. + /// + /// \param InInitList true if we are initializing from an expression within + /// an initializer list. This disallows narrowing conversions in C++11 + /// onwards. InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, - MultiExprArg Args); - + MultiExprArg Args, + bool InInitList = false); + void InitializeFrom(Sema &S, const InitializedEntity &Entity, + const InitializationKind &Kind, MultiExprArg Args, + bool InInitList); + ~InitializationSequence(); /// \brief Perform the actual initialization of the given entity based on @@ -841,12 +900,12 @@ public: void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; } /// \brief Determine whether the initialization sequence is valid. - operator bool() const { return !Failed(); } + LLVM_EXPLICIT operator bool() const { return !Failed(); } /// \brief Determine whether the initialization sequence is invalid. bool Failed() const { return SequenceKind == FailedSequence; } - - typedef SmallVector<Step, 4>::const_iterator step_iterator; + + typedef SmallVectorImpl<Step>::const_iterator step_iterator; step_iterator step_begin() const { return Steps.begin(); } step_iterator step_end() const { return Steps.end(); } @@ -930,7 +989,7 @@ public: /// \brief Add a new step that applies an implicit conversion sequence. void AddConversionSequenceStep(const ImplicitConversionSequence &ICS, - QualType T); + QualType T, bool TopLevelOfInitList = false); /// \brief Add a list-initialization step. void AddListInitializationStep(QualType T); diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h b/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h index 3e7e3a1..105c879 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h @@ -139,7 +139,8 @@ public: Redecl(Redecl != Sema::NotForRedeclaration), HideTags(true), Diagnose(Redecl == Sema::NotForRedeclaration), - AllowHidden(Redecl == Sema::ForRedeclaration) + AllowHidden(Redecl == Sema::ForRedeclaration), + Shadowed(false) { configure(); } @@ -160,7 +161,8 @@ public: Redecl(Redecl != Sema::NotForRedeclaration), HideTags(true), Diagnose(Redecl == Sema::NotForRedeclaration), - AllowHidden(Redecl == Sema::ForRedeclaration) + AllowHidden(Redecl == Sema::ForRedeclaration), + Shadowed(false) { configure(); } @@ -179,7 +181,8 @@ public: Redecl(Other.Redecl), HideTags(Other.HideTags), Diagnose(false), - AllowHidden(Other.AllowHidden) + AllowHidden(Other.AllowHidden), + Shadowed(false) {} ~LookupResult() { @@ -283,33 +286,36 @@ public: /// \brief Determine whether the given declaration is visible to the /// program. - static bool isVisible(NamedDecl *D) { + static bool isVisible(Sema &SemaRef, NamedDecl *D) { // If this declaration is not hidden, it's visible. if (!D->isHidden()) return true; - - // FIXME: We should be allowed to refer to a module-private name from - // within the same module, e.g., during template instantiation. - // This requires us know which module a particular declaration came from. - return false; + + if (SemaRef.ActiveTemplateInstantiations.empty()) + return false; + + // During template instantiation, we can refer to hidden declarations, if + // they were visible in any module along the path of instantiation. + return isVisibleSlow(SemaRef, D); } - + /// \brief Retrieve the accepted (re)declaration of the given declaration, /// if there is one. NamedDecl *getAcceptableDecl(NamedDecl *D) const { if (!D->isInIdentifierNamespace(IDNS)) return 0; - - if (isHiddenDeclarationVisible() || isVisible(D)) + + if (isHiddenDeclarationVisible() || isVisible(SemaRef, D)) return D; - + return getAcceptableDeclSlow(D); } - + private: + static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D); NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const; + public: - /// \brief Returns the identifier namespace mask for this lookup. unsigned getIdentifierNamespace() const { return IDNS; @@ -390,7 +396,15 @@ public: assert(ResultKind == NotFound && Decls.empty()); ResultKind = NotFoundInCurrentInstantiation; } - + + /// \brief Determine whether the lookup result was shadowed by some other + /// declaration that lookup ignored. + bool isShadowed() const { return Shadowed; } + + /// \brief Note that we found and ignored a declaration while performing + /// lookup. + void setShadowed() { Shadowed = true; } + /// \brief Resolves the result kind of the lookup, possibly hiding /// decls. /// @@ -479,6 +493,7 @@ public: if (Paths) deletePaths(Paths); Paths = NULL; NamingClass = 0; + Shadowed = false; } /// \brief Clears out any current state and re-initializes for a @@ -598,6 +613,13 @@ public: return Filter(*this); } + void setFindLocalExtern(bool FindLocalExtern) { + if (FindLocalExtern) + IDNS |= Decl::IDNS_LocalExtern; + else + IDNS &= ~Decl::IDNS_LocalExtern; + } + private: void diagnose() { if (isAmbiguous()) @@ -657,34 +679,44 @@ private: /// \brief True if we should allow hidden declarations to be 'visible'. bool AllowHidden; + + /// \brief True if the found declarations were shadowed by some other + /// declaration that we skipped. This only happens when \c LookupKind + /// is \c LookupRedeclarationWithLinkage. + bool Shadowed; }; - /// \brief Consumes visible declarations found when searching for - /// all visible names within a given scope or context. +/// \brief Consumes visible declarations found when searching for +/// all visible names within a given scope or context. +/// +/// This abstract class is meant to be subclassed by clients of \c +/// Sema::LookupVisibleDecls(), each of which should override the \c +/// FoundDecl() function to process declarations as they are found. +class VisibleDeclConsumer { +public: + /// \brief Destroys the visible declaration consumer. + virtual ~VisibleDeclConsumer(); + + /// \brief Determine whether hidden declarations (from unimported + /// modules) should be given to this consumer. By default, they + /// are not included. + virtual bool includeHiddenDecls() const; + + /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a + /// declaration visible from the current scope or context. /// - /// This abstract class is meant to be subclassed by clients of \c - /// Sema::LookupVisibleDecls(), each of which should override the \c - /// FoundDecl() function to process declarations as they are found. - class VisibleDeclConsumer { - public: - /// \brief Destroys the visible declaration consumer. - virtual ~VisibleDeclConsumer(); - - /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a - /// declaration visible from the current scope or context. - /// - /// \param ND the declaration found. - /// - /// \param Hiding a declaration that hides the declaration \p ND, - /// or NULL if no such declaration exists. - /// - /// \param Ctx the original context from which the lookup started. - /// - /// \param InBaseClass whether this declaration was found in base - /// class of the context we searched. - virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, - bool InBaseClass) = 0; - }; + /// \param ND the declaration found. + /// + /// \param Hiding a declaration that hides the declaration \p ND, + /// or NULL if no such declaration exists. + /// + /// \param Ctx the original context from which the lookup started. + /// + /// \param InBaseClass whether this declaration was found in base + /// class of the context we searched. + virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, + bool InBaseClass) = 0; +}; /// \brief A class for storing results from argument-dependent lookup. class ADLResult { @@ -701,7 +733,8 @@ public: Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); } - class iterator { + class iterator + : public std::iterator<std::forward_iterator_tag, NamedDecl *> { typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator; inner_iterator iter; @@ -713,7 +746,7 @@ public: iterator &operator++() { ++iter; return *this; } iterator operator++(int) { return iterator(iter++); } - NamedDecl *operator*() const { return iter->second; } + value_type operator*() const { return iter->second; } bool operator==(const iterator &other) const { return iter == other.iter; } bool operator!=(const iterator &other) const { return iter != other.iter; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h index ff87d05..e9ba479 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -322,6 +322,36 @@ public: virtual void ReadPendingInstantiations( SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending); + /// \brief Read the set of late parsed template functions for this source. + /// + /// The external source should insert its own late parsed template functions + /// into the map. Note that this routine may be invoked multiple times; the + /// external source should take care not to introduce the same map entries + /// repeatedly. + virtual void ReadLateParsedTemplates( + llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap); + + /// \copydoc ExternalSemaSource::CorrectTypo + /// \note Returns the first nonempty correction. + virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, + int LookupKind, Scope *S, CXXScopeSpec *SS, + CorrectionCandidateCallback &CCC, + DeclContext *MemberContext, + bool EnteringContext, + const ObjCObjectPointerType *OPT); + + /// \brief Produces a diagnostic note if one of the attached sources + /// contains a complete definition for \p T. Queries the sources in list + /// order until the first one claims that a diagnostic was produced. + /// + /// \param Loc the location at which a complete type was required but not + /// provided + /// + /// \param T the \c QualType that should have been complete at \p Loc + /// + /// \return true if a diagnostic was produced, false otherwise. + virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc, QualType T); + // isa/cast/dyn_cast support static bool classof(const MultiplexExternalSemaSource*) { return true; } //static bool classof(const ExternalSemaSource*) { return true; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Overload.h b/contrib/llvm/tools/clang/include/clang/Sema/Overload.h index c685843..b8bd14a 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Overload.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Overload.h @@ -22,6 +22,7 @@ #include "clang/AST/Type.h" #include "clang/AST/UnresolvedSet.h" #include "clang/Sema/SemaFixItUtils.h" +#include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" @@ -241,7 +242,7 @@ namespace clang { QualType &ConstantType) const; bool isPointerConversionToBool() const; bool isPointerConversionToVoidPointer(ASTContext& Context) const; - void DebugPrint() const; + void dump() const; }; /// UserDefinedConversionSequence - Represents a user-defined @@ -287,7 +288,7 @@ namespace clang { /// that refers to \c ConversionFunction. DeclAccessPair FoundConversionFunction; - void DebugPrint() const; + void dump() const; }; /// Represents an ambiguous user-defined conversion sequence. @@ -405,9 +406,6 @@ namespace clang { /// ConversionKind - The kind of implicit conversion sequence. unsigned ConversionKind : 30; - /// \brief Whether the argument is an initializer list. - bool ListInitializationSequence : 1; - /// \brief Whether the target is really a std::initializer_list, and the /// sequence only represents the worst element conversion. bool StdInitializerListElement : 1; @@ -440,16 +438,14 @@ namespace clang { BadConversionSequence Bad; }; - ImplicitConversionSequence() - : ConversionKind(Uninitialized), ListInitializationSequence(false), - StdInitializerListElement(false) + ImplicitConversionSequence() + : ConversionKind(Uninitialized), StdInitializerListElement(false) {} ~ImplicitConversionSequence() { destruct(); } ImplicitConversionSequence(const ImplicitConversionSequence &Other) - : ConversionKind(Other.ConversionKind), - ListInitializationSequence(Other.ListInitializationSequence), + : ConversionKind(Other.ConversionKind), StdInitializerListElement(Other.StdInitializerListElement) { switch (ConversionKind) { @@ -535,16 +531,6 @@ namespace clang { Ambiguous.construct(); } - /// \brief Whether this sequence was created by the rules of - /// list-initialization sequences. - bool isListInitializationSequence() const { - return ListInitializationSequence; - } - - void setListInitializationSequence() { - ListInitializationSequence = true; - } - /// \brief Whether the target is really a std::initializer_list, and the /// sequence only represents the worst element conversion. bool isStdInitializerListElement() const { @@ -568,7 +554,7 @@ namespace clang { SourceLocation CaretLoc, const PartialDiagnostic &PDiag) const; - void DebugPrint() const; + void dump() const; }; enum OverloadFailureKind { @@ -656,53 +642,6 @@ namespace clang { /// \brief The number of call arguments that were explicitly provided, /// to be used while performing partial ordering of function templates. unsigned ExplicitCallArguments; - - /// A structure used to record information about a failed - /// template argument deduction. - struct DeductionFailureInfo { - /// A Sema::TemplateDeductionResult. - unsigned Result : 8; - - /// \brief Indicates whether a diagnostic is stored in Diagnostic. - unsigned HasDiagnostic : 1; - - /// \brief Opaque pointer containing additional data about - /// this deduction failure. - void *Data; - - /// \brief A diagnostic indicating why deduction failed. - union { - void *Align; - char Diagnostic[sizeof(PartialDiagnosticAt)]; - }; - - /// \brief Retrieve the diagnostic which caused this deduction failure, - /// if any. - PartialDiagnosticAt *getSFINAEDiagnostic(); - - /// \brief Retrieve the template parameter this deduction failure - /// refers to, if any. - TemplateParameter getTemplateParameter(); - - /// \brief Retrieve the template argument list associated with this - /// deduction failure, if any. - TemplateArgumentList *getTemplateArgumentList(); - - /// \brief Return the first template argument this deduction failure - /// refers to, if any. - const TemplateArgument *getFirstArg(); - - /// \brief Return the second template argument this deduction failure - /// refers to, if any. - const TemplateArgument *getSecondArg(); - - /// \brief Return the expression this deduction failure refers to, - /// if any. - Expr *getExpr(); - - /// \brief Free any memory associated with this deduction failure. - void Destroy(); - }; union { DeductionFailureInfo DeductionFailure; @@ -773,7 +712,7 @@ namespace clang { /// \brief Clear out all of the candidates. void clear(); - typedef SmallVector<OverloadCandidate, 16>::iterator iterator; + typedef SmallVectorImpl<OverloadCandidate>::iterator iterator; iterator begin() { return Candidates.begin(); } iterator end() { return Candidates.end(); } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h b/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h index c3d1f4e..b7d7710 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Ownership.h @@ -33,8 +33,12 @@ namespace clang { class TemplateName; class TemplateParameterList; - /// OpaquePtr - This is a very simple POD type that wraps a pointer that the - /// Parser doesn't know about but that Sema or another client does. The UID + /// \brief Wrapper for void* pointer. + /// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like + /// a pointer. + /// + /// This is a very simple POD type that wraps a pointer that the Parser + /// doesn't know about but that Sema or another client does. The PtrTy /// template argument is used to make sure that "Decl" pointers are not /// compatible with "Type" pointers for example. template <class PtrTy> @@ -49,11 +53,21 @@ namespace clang { static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } - template <typename T> T* getAs() const { + /// \brief Returns plain pointer to the entity pointed by this wrapper. + /// \tparam PointeeT Type of pointed entity. + /// + /// It is identical to getPtrAs<PointeeT*>. + template <typename PointeeT> PointeeT* getPtrTo() const { return get(); } - template <typename T> T getAsVal() const { + /// \brief Returns pointer converted to the specified type. + /// \tparam PtrT Result pointer type. There must be implicit conversion + /// from PtrTy to PtrT. + /// + /// In contrast to getPtrTo, this method allows the return type to be + /// a smart pointer. + template <typename PtrT> PtrT getPtrAs() const { return get(); } @@ -65,7 +79,7 @@ namespace clang { Ptr = Traits::getAsVoidPointer(P); } - operator bool() const { return Ptr != 0; } + LLVM_EXPLICIT operator bool() const { return Ptr != 0; } void *getAsOpaquePtr() const { return Ptr; } static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Scope.h b/contrib/llvm/tools/clang/include/clang/Sema/Scope.h index d016b9b..249a4c7 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Scope.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Scope.h @@ -91,7 +91,10 @@ public: TryScope = 0x2000, /// \brief This is the scope for a function-level C++ try or catch scope. - FnTryCatchScope = 0x4000 + FnTryCatchScope = 0x4000, + + /// \brief This is the scope of OpenMP executable directive + OpenMPDirectiveScope = 0x8000 }; private: /// The parent scope for this scope. This is null for the translation-unit @@ -143,11 +146,10 @@ private: typedef llvm::SmallPtrSet<Decl *, 32> DeclSetTy; DeclSetTy DeclsInScope; - /// Entity - The entity with which this scope is associated. For + /// The DeclContext with which this scope is associated. For /// example, the entity of a class scope is the class itself, the - /// entity of a function scope is a function, etc. This field is - /// maintained by the Action implementation. - void *Entity; + /// entity of a function scope is a function, etc. + DeclContext *Entity; typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy; UsingDirectivesTy UsingDirectives; @@ -236,8 +238,8 @@ public: return DeclsInScope.count(D) != 0; } - void* getEntity() const { return Entity; } - void setEntity(void *E) { Entity = E; } + DeclContext *getEntity() const { return Entity; } + void setEntity(DeclContext *E) { Entity = E; } bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); } @@ -301,7 +303,12 @@ public: } return false; } - + + /// \brief Determines whether this scope is the OpenMP directive scope + bool isOpenMPDirectiveScope() const { + return (getFlags() & Scope::OpenMPDirectiveScope); + } + /// \brief Determine whether this scope is a C++ 'try' block. bool isTryScope() const { return getFlags() & Scope::TryScope; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h index b232b59..06afe1a 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h @@ -18,8 +18,11 @@ #include "clang/AST/Type.h" #include "clang/Basic/CapturedStmt.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Sema/Ownership.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" +#include <algorithm> namespace clang { @@ -27,6 +30,7 @@ class Decl; class BlockDecl; class CapturedDecl; class CXXMethodDecl; +class FieldDecl; class ObjCPropertyDecl; class IdentifierInfo; class ImplicitParamDecl; @@ -34,8 +38,11 @@ class LabelDecl; class ReturnStmt; class Scope; class SwitchStmt; +class TemplateTypeParmDecl; +class TemplateParameterList; class VarDecl; class DeclRefExpr; +class MemberExpr; class ObjCIvarRefExpr; class ObjCPropertyRefExpr; class ObjCMessageExpr; @@ -330,60 +337,78 @@ public: ImplicitCaptureStyle ImpCaptureStyle; class Capture { - // There are two categories of capture: capturing 'this', and capturing - // local variables. There are three ways to capture a local variable: - // capture by copy in the C++11 sense, capture by reference - // in the C++11 sense, and __block capture. Lambdas explicitly specify - // capture by copy or capture by reference. For blocks, __block capture - // applies to variables with that annotation, variables of reference type - // are captured by reference, and other variables are captured by copy. + // There are three categories of capture: capturing 'this', capturing + // local variables, and C++1y initialized captures (which can have an + // arbitrary initializer, and don't really capture in the traditional + // sense at all). + // + // There are three ways to capture a local variable: + // - capture by copy in the C++11 sense, + // - capture by reference in the C++11 sense, and + // - __block capture. + // Lambdas explicitly specify capture by copy or capture by reference. + // For blocks, __block capture applies to variables with that annotation, + // variables of reference type are captured by reference, and other + // variables are captured by copy. enum CaptureKind { - Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block + Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This }; - // The variable being captured (if we are not capturing 'this'), - // and misc bits descibing the capture. - llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind; + /// The variable being captured (if we are not capturing 'this') and whether + /// this is a nested capture. + llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested; - // Expression to initialize a field of the given type, and whether this - // is a nested capture; the expression is only required if we are - // capturing ByVal and the variable's type has a non-trivial - // copy constructor. - llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested; + /// Expression to initialize a field of the given type, and the kind of + /// capture (if this is a capture and not an init-capture). The expression + /// is only required if we are capturing ByVal and the variable's type has + /// a non-trivial copy constructor. + llvm::PointerIntPair<Expr*, 2, CaptureKind> InitExprAndCaptureKind; - /// \brief The source location at which the first capture occurred.. + /// \brief The source location at which the first capture occurred. SourceLocation Loc; - + /// \brief The location of the ellipsis that expands a parameter pack. SourceLocation EllipsisLoc; - + /// \brief The type as it was captured, which is in effect the type of the /// non-static data member that would hold the capture. QualType CaptureType; - + public: - Capture(VarDecl *Var, bool block, bool byRef, bool isNested, - SourceLocation Loc, SourceLocation EllipsisLoc, + Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, + SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, Expr *Cpy) - : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy), - CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc), - CaptureType(CaptureType){} + : VarAndNested(Var, IsNested), + InitExprAndCaptureKind(Cpy, Block ? Cap_Block : + ByRef ? Cap_ByRef : Cap_ByCopy), + Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {} enum IsThisCapture { ThisCapture }; - Capture(IsThisCapture, bool isNested, SourceLocation Loc, + Capture(IsThisCapture, bool IsNested, SourceLocation Loc, QualType CaptureType, Expr *Cpy) - : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc), - EllipsisLoc(), CaptureType(CaptureType) { } + : VarAndNested(0, IsNested), + InitExprAndCaptureKind(Cpy, Cap_This), + Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {} - bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; } - bool isVariableCapture() const { return !isThisCapture(); } - bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; } - bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; } - bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; } - bool isNested() { return CopyExprAndNested.getInt(); } + bool isThisCapture() const { + return InitExprAndCaptureKind.getInt() == Cap_This; + } + bool isVariableCapture() const { + return InitExprAndCaptureKind.getInt() != Cap_This; + } + bool isCopyCapture() const { + return InitExprAndCaptureKind.getInt() == Cap_ByCopy; + } + bool isReferenceCapture() const { + return InitExprAndCaptureKind.getInt() == Cap_ByRef; + } + bool isBlockCapture() const { + return InitExprAndCaptureKind.getInt() == Cap_Block; + } + bool isNested() { return VarAndNested.getInt(); } VarDecl *getVariable() const { - return VarAndKind.getPointer(); + return VarAndNested.getPointer(); } /// \brief Retrieve the location at which this variable was captured. @@ -398,8 +423,8 @@ public: /// that would store this capture. QualType getCaptureType() const { return CaptureType; } - Expr *getCopyExpr() const { - return CopyExprAndNested.getPointer(); + Expr *getInitExpr() const { + return InitExprAndCaptureKind.getPointer(); } }; @@ -529,6 +554,8 @@ public: switch (CapRegionKind) { case CR_Default: return "default captured statement"; + case CR_OpenMP: + return "OpenMP region"; } llvm_unreachable("Invalid captured region kind!"); } @@ -543,19 +570,23 @@ public: /// \brief The class that describes the lambda. CXXRecordDecl *Lambda; - /// \brief The class that describes the lambda. + /// \brief The lambda's compiler-generated \c operator(). CXXMethodDecl *CallOperator; /// \brief Source range covering the lambda introducer [...]. SourceRange IntroducerRange; - /// \brief The number of captures in the \c Captures list that are + /// \brief Source location of the '&' or '=' specifying the default capture + /// type, if any. + SourceLocation CaptureDefaultLoc; + + /// \brief The number of captures in the \c Captures list that are /// explicit captures. unsigned NumExplicitCaptures; /// \brief Whether this is a mutable lambda. bool Mutable; - + /// \brief Whether the (empty) parameter list is explicit. bool ExplicitParams; @@ -572,25 +603,169 @@ public: /// its list of array index variables. SmallVector<unsigned, 4> ArrayIndexStarts; - LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda, - CXXMethodDecl *CallOperator) - : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), - CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), - ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false) + /// \brief If this is a generic lambda, use this as the depth of + /// each 'auto' parameter, during initial AST construction. + unsigned AutoTemplateParameterDepth; + + /// \brief Store the list of the auto parameters for a generic lambda. + /// If this is a generic lambda, store the list of the auto + /// parameters converted into TemplateTypeParmDecls into a vector + /// that can be used to construct the generic lambda's template + /// parameter list, during initial AST construction. + SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams; + + /// If this is a generic lambda, and the template parameter + /// list has been created (from the AutoTemplateParams) then + /// store a reference to it (cache it to avoid reconstructing it). + TemplateParameterList *GLTemplateParameterList; + + /// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs + /// or MemberExprs) that refer to local variables in a generic lambda + /// or a lambda in a potentially-evaluated-if-used context. + /// + /// Potentially capturable variables of a nested lambda that might need + /// to be captured by the lambda are housed here. + /// This is specifically useful for generic lambdas or + /// lambdas within a a potentially evaluated-if-used context. + /// If an enclosing variable is named in an expression of a lambda nested + /// within a generic lambda, we don't always know know whether the variable + /// will truly be odr-used (i.e. need to be captured) by that nested lambda, + /// until its instantiation. But we still need to capture it in the + /// enclosing lambda if all intervening lambdas can capture the variable. + + llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs; + + /// \brief Contains all variable-referring-expressions that refer + /// to local variables that are usable as constant expressions and + /// do not involve an odr-use (they may still need to be captured + /// if the enclosing full-expression is instantiation dependent). + llvm::SmallSet<Expr*, 8> NonODRUsedCapturingExprs; + + SourceLocation PotentialThisCaptureLocation; + + LambdaScopeInfo(DiagnosticsEngine &Diag) + : CapturingScopeInfo(Diag, ImpCap_None), Lambda(0), + CallOperator(0), NumExplicitCaptures(0), Mutable(false), + ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false), + AutoTemplateParameterDepth(0), GLTemplateParameterList(0) { Kind = SK_Lambda; } virtual ~LambdaScopeInfo(); - /// \brief Note when + /// \brief Note when all explicit captures have been added. void finishedExplicitCaptures() { NumExplicitCaptures = Captures.size(); } static bool classof(const FunctionScopeInfo *FSI) { - return FSI->Kind == SK_Lambda; + return FSI->Kind == SK_Lambda; } + + /// + /// \brief Add a variable that might potentially be captured by the + /// lambda and therefore the enclosing lambdas. + /// + /// This is also used by enclosing lambda's to speculatively capture + /// variables that nested lambda's - depending on their enclosing + /// specialization - might need to capture. + /// Consider: + /// void f(int, int); <-- don't capture + /// void f(const int&, double); <-- capture + /// void foo() { + /// const int x = 10; + /// auto L = [=](auto a) { // capture 'x' + /// return [=](auto b) { + /// f(x, a); // we may or may not need to capture 'x' + /// }; + /// }; + /// } + void addPotentialCapture(Expr *VarExpr) { + assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr)); + PotentiallyCapturingExprs.push_back(VarExpr); + } + + void addPotentialThisCapture(SourceLocation Loc) { + PotentialThisCaptureLocation = Loc; + } + bool hasPotentialThisCapture() const { + return PotentialThisCaptureLocation.isValid(); + } + + /// \brief Mark a variable's reference in a lambda as non-odr using. + /// + /// For generic lambdas, if a variable is named in a potentially evaluated + /// expression, where the enclosing full expression is dependent then we + /// must capture the variable (given a default capture). + /// This is accomplished by recording all references to variables + /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of + /// PotentialCaptures. All such variables have to be captured by that lambda, + /// except for as described below. + /// If that variable is usable as a constant expression and is named in a + /// manner that does not involve its odr-use (e.g. undergoes + /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the + /// act of analyzing the enclosing full expression (ActOnFinishFullExpr) + /// if we can determine that the full expression is not instantiation- + /// dependent, then we can entirely avoid its capture. + ///
+ /// const int n = 0;
+ /// [&] (auto x) {
+ /// (void)+n + x;
+ /// }; + /// Interestingly, this strategy would involve a capture of n, even though + /// it's obviously not odr-used here, because the full-expression is + /// instantiation-dependent. It could be useful to avoid capturing such + /// variables, even when they are referred to in an instantiation-dependent + /// expression, if we can unambiguously determine that they shall never be + /// odr-used. This would involve removal of the variable-referring-expression + /// from the array of PotentialCaptures during the lvalue-to-rvalue + /// conversions. But per the working draft N3797, (post-chicago 2013) we must + /// capture such variables. + /// Before anyone is tempted to implement a strategy for not-capturing 'n', + /// consider the insightful warning in: + /// /cfe-commits/Week-of-Mon-20131104/092596.html + /// "The problem is that the set of captures for a lambda is part of the ABI
+ /// (since lambda layout can be made visible through inline functions and the
+ /// like), and there are no guarantees as to which cases we'll manage to build
+ /// an lvalue-to-rvalue conversion in, when parsing a template -- some
+ /// seemingly harmless change elsewhere in Sema could cause us to start or stop
+ /// building such a node. So we need a rule that anyone can implement and get
+ /// exactly the same result". + /// + void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) { + assert(isa<DeclRefExpr>(CapturingVarExpr) + || isa<MemberExpr>(CapturingVarExpr)); + NonODRUsedCapturingExprs.insert(CapturingVarExpr); + } + bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) { + assert(isa<DeclRefExpr>(CapturingVarExpr) + || isa<MemberExpr>(CapturingVarExpr)); + return NonODRUsedCapturingExprs.count(CapturingVarExpr); + } + void removePotentialCapture(Expr *E) { + PotentiallyCapturingExprs.erase( + std::remove(PotentiallyCapturingExprs.begin(), + PotentiallyCapturingExprs.end(), E), + PotentiallyCapturingExprs.end()); + } + void clearPotentialCaptures() { + PotentiallyCapturingExprs.clear(); + PotentialThisCaptureLocation = SourceLocation(); + } + unsigned getNumPotentialVariableCaptures() const { + return PotentiallyCapturingExprs.size(); + } + + bool hasPotentialCaptures() const { + return getNumPotentialVariableCaptures() || + PotentialThisCaptureLocation.isValid(); + } + + // When passed the index, returns the VarDecl and Expr associated + // with the index. + void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E); + }; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h index d7c80f2..48794d6 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h @@ -20,12 +20,13 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExternalASTSource.h" -#include "clang/AST/LambdaMangleContext.h" +#include "clang/AST/MangleNumberingContext.h" #include "clang/AST/NSAPI.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/ExpressionTraits.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" @@ -49,6 +50,7 @@ #include "llvm/MC/MCParser/MCAsmParser.h" #include <deque> #include <string> +#include <vector> namespace llvm { class APSInt; @@ -85,6 +87,7 @@ namespace clang { class ClassTemplateDecl; class ClassTemplatePartialSpecializationDecl; class ClassTemplateSpecializationDecl; + class VarTemplatePartialSpecializationDecl; class CodeCompleteConsumer; class CodeCompletionAllocator; class CodeCompletionTUInfo; @@ -136,6 +139,7 @@ namespace clang { class ObjCPropertyDecl; class ObjCProtocolDecl; class OMPThreadPrivateDecl; + class OMPClause; class OverloadCandidateSet; class OverloadExpr; class ParenListExpr; @@ -170,9 +174,12 @@ namespace clang { class UsingShadowDecl; class ValueDecl; class VarDecl; + class VarTemplateSpecializationDecl; class VisibilityAttr; class VisibleDeclConsumer; class IndirectFieldDecl; + struct DeductionFailureInfo; + class TemplateSpecCandidateSet; namespace sema { class AccessedEntity; @@ -215,7 +222,7 @@ class Sema { // it will keep having external linkage. If it has internal linkage, we // will not link it. Since it has no previous decls, it will remain // with internal linkage. - return !Old->isHidden() || New->hasExternalLinkage(); + return !Old->isHidden() || New->isExternallyVisible(); } public: @@ -274,6 +281,12 @@ public: /// element type here is ExprWithCleanups::Object. SmallVector<BlockDecl*, 8> ExprCleanupObjects; + /// \brief Store a list of either DeclRefExprs or MemberExprs + /// that contain a reference to a variable (constant) that may or may not + /// be odr-used in this Expr, and we won't know until all lvalue-to-rvalue + /// and discarded value conversions have been applied to all subexpressions + /// of the enclosing full expression. This is cleared at the end of each + /// full expression. llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs; /// \brief Stack containing information about each of the nested @@ -340,8 +353,7 @@ public: llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternCDecls; /// \brief Look for a locally scoped extern "C" declaration by the given name. - llvm::DenseMap<DeclarationName, NamedDecl *>::iterator - findLocallyScopedExternCDecl(DeclarationName Name); + NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name); typedef LazyVector<VarDecl *, ExternalSemaSource, &ExternalSemaSource::ReadTentativeDefinitions, 2, 2> @@ -366,11 +378,6 @@ public: /// cycle detection at the end of the TU. DelegatingCtorDeclsType DelegatingCtorDecls; - /// \brief All the destructors seen during a class definition that had their - /// exception spec computation delayed because it depended on an unparsed - /// exception spec. - SmallVector<CXXDestructorDecl*, 2> DelayedDestructorExceptionSpecs; - /// \brief All the overriding destructors seen during a class definition /// (there could be multiple due to nested classes) that had their exception /// spec checks delayed, plus the overridden destructor. @@ -388,8 +395,12 @@ public: SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2> DelayedDefaultedMemberExceptionSpecs; + typedef llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> + LateParsedTemplateMapT; + LateParsedTemplateMapT LateParsedTemplateMap; + /// \brief Callback to the parser to parse templated functions when needed. - typedef void LateTemplateParserCB(void *P, const FunctionDecl *FD); + typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT); LateTemplateParserCB *LateTemplateParser; void *OpaqueParser; @@ -621,7 +632,7 @@ public: /// \brief The current context is "potentially evaluated" in C++11 terms, /// but the expression is evaluated at compile-time (like the values of - /// cases in a switch statment). + /// cases in a switch statement). ConstantEvaluated, /// \brief The current expression is potentially evaluated at run time, @@ -662,17 +673,17 @@ public: /// is indeed an unevaluated context. SmallVector<LambdaExpr *, 2> Lambdas; - /// \brief The declaration that provides context for the lambda expression - /// if the normal declaration context does not suffice, e.g., in a - /// default function argument. - Decl *LambdaContextDecl; + /// \brief The declaration that provides context for lambda expressions + /// and block literals if the normal declaration context does not + /// suffice, e.g., in a default function argument. + Decl *ManglingContextDecl; /// \brief The context information used to mangle lambda expressions - /// within this context. + /// and block literals within this context. /// /// This mangling information is allocated lazily, since most contexts - /// do not have lambda expressions. - IntrusiveRefCntPtr<LambdaMangleContext> LambdaMangle; + /// do not have lambda expressions or block literals. + IntrusiveRefCntPtr<MangleNumberingContext> MangleNumbering; /// \brief If we are processing a decltype type, a set of call expressions /// for which we have deferred checking the completeness of the return type. @@ -685,19 +696,15 @@ public: ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, unsigned NumCleanupObjects, bool ParentNeedsCleanups, - Decl *LambdaContextDecl, + Decl *ManglingContextDecl, bool IsDecltype) : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups), IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects), - LambdaContextDecl(LambdaContextDecl), LambdaMangle() { } - - /// \brief Retrieve the mangling context for lambdas. - LambdaMangleContext &getLambdaMangleContext() { - assert(LambdaContextDecl && "Need to have a lambda context declaration"); - if (!LambdaMangle) - LambdaMangle = new LambdaMangleContext; - return *LambdaMangle; - } + ManglingContextDecl(ManglingContextDecl), MangleNumbering() { } + + /// \brief Retrieve the mangling numbering context, used to consistently + /// number constructs like lambdas for mangling. + MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx); bool isUnevaluated() const { return Context == Unevaluated || Context == UnevaluatedAbstract; @@ -707,6 +714,18 @@ public: /// A stack of expression evaluation contexts. SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts; + /// \brief Compute the mangling number context for a lambda expression or + /// block literal. + /// + /// \param DC - The DeclContext containing the lambda expression or + /// block literal. + /// \param[out] ManglingContextDecl - Returns the ManglingContextDecl + /// associated with the context, if relevant. + MangleNumberingContext *getCurrentMangleNumberContext( + const DeclContext *DC, + Decl *&ManglingContextDecl); + + /// SpecialMemberOverloadResult - The overloading result for a special member /// function. /// @@ -775,7 +794,7 @@ public: /// Obtain a sorted list of functions that are undefined but ODR-used. void getUndefinedButUsed( - llvm::SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined); + SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined); typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods; typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool; @@ -905,6 +924,15 @@ public: // Dispatch to Sema to emit the diagnostic. SemaRef.EmitCurrentDiagnostic(DiagID); } + + /// Teach operator<< to produce an object of the correct type. + template<typename T> + friend const SemaDiagnosticBuilder &operator<<( + const SemaDiagnosticBuilder &Diag, const T &Value) { + const DiagnosticBuilder &BaseDiag = Diag; + BaseDiag << Value; + return Diag; + } }; /// \brief Emit a diagnostic. @@ -922,8 +950,9 @@ public: bool findMacroSpelling(SourceLocation &loc, StringRef name); /// \brief Get a string to suggest for zero-initialization of a type. - std::string getFixItZeroInitializerForType(QualType T) const; - std::string getFixItZeroLiteralForType(QualType T) const; + std::string + getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const; + std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const; ExprResult Owned(Expr* E) { return E; } ExprResult Owned(ExprResult R) { return R; } @@ -937,7 +966,13 @@ public: void PushFunctionScope(); void PushBlockScope(Scope *BlockScope, BlockDecl *Block); - void PushLambdaScope(CXXRecordDecl *Lambda, CXXMethodDecl *CallOperator); + sema::LambdaScopeInfo *PushLambdaScope(); + + /// \brief This is used to inform Sema what the current TemplateParameterDepth + /// is during Parsing. Currently it is used to pass on the depth + /// when parsing generic lambda 'auto' parameters. + void RecordParsingTemplateParameterDepth(unsigned Depth); + void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, RecordDecl *RD, CapturedRegionKind K); @@ -947,7 +982,13 @@ public: sema::FunctionScopeInfo *getCurFunction() const { return FunctionScopes.back(); } - + + template <typename ExprT> + void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) { + if (!isUnevaluatedContext()) + getCurFunction()->recordUseOfWeak(E, IsRead); + } + void PushCompoundScope(); void PopCompoundScope(); @@ -958,14 +999,17 @@ public: /// \brief Retrieve the current block, if any. sema::BlockScopeInfo *getCurBlock(); - /// \brief Retrieve the current lambda expression, if any. + /// \brief Retrieve the current lambda scope info, if any. sema::LambdaScopeInfo *getCurLambda(); + /// \brief Retrieve the current generic lambda info, if any. + sema::LambdaScopeInfo *getCurGenericLambda(); + /// \brief Retrieve the current captured region, if any. sema::CapturedRegionScopeInfo *getCurCapturedRegion(); /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls - SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; } + SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; } void ActOnComment(SourceRange Comment); @@ -987,6 +1031,8 @@ public: QualType BuildExtVectorType(QualType T, Expr *ArraySize, SourceLocation AttrLoc); + bool CheckFunctionReturnType(QualType T, SourceLocation Loc); + /// \brief Build a function type. /// /// This routine checks the function type according to C++ rules and @@ -1152,6 +1198,10 @@ public: virtual ~BoundTypeDiagnoser3() { } }; +private: + bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, + TypeDiagnoser &Diagnoser); +public: bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser); bool RequireCompleteType(SourceLocation Loc, QualType T, @@ -1287,6 +1337,7 @@ public: NC_Expression, NC_NestedNameSpecifier, NC_TypeTemplate, + NC_VarTemplate, NC_FunctionTemplate }; @@ -1325,6 +1376,12 @@ public: return Result; } + static NameClassification VarTemplate(TemplateName Name) { + NameClassification Result(NC_VarTemplate); + Result.Template = Name; + return Result; + } + static NameClassification FunctionTemplate(TemplateName Name) { NameClassification Result(NC_FunctionTemplate); Result.Template = Name; @@ -1344,13 +1401,22 @@ public: } TemplateName getTemplateName() const { - assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate); + assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || + Kind == NC_VarTemplate); return Template; } TemplateNameKind getTemplateNameKind() const { - assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate); - return Kind == NC_TypeTemplate? TNK_Type_template : TNK_Function_template; + switch (Kind) { + case NC_TypeTemplate: + return TNK_Type_template; + case NC_FunctionTemplate: + return TNK_Function_template; + case NC_VarTemplate: + return TNK_Var_template; + default: + llvm_unreachable("unsupported name classification."); + } } }; @@ -1390,13 +1456,12 @@ public: NamedDecl *HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists); - void RegisterLocallyScopedExternCDecl(NamedDecl *ND, - const LookupResult &Previous, - Scope *S); + void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S); bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info); bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, DeclarationName Name, SourceLocation Loc); + static bool adjustContextForLocalExternDecl(DeclContext *&DC); void DiagnoseFunctionSpecifiers(const DeclSpec &DS); void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R); void CheckShadow(Scope *S, VarDecl *D); @@ -1407,10 +1472,11 @@ public: LookupResult &Previous); NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D, LookupResult &Previous, bool &Redeclaration); - NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, + NamedDecl *ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, - MultiTemplateParamsArg TemplateParamLists); + MultiTemplateParamsArg TemplateParamLists, + bool &AddToScope); // Returns true if the variable declaration is a redeclaration bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckVariableDeclarationType(VarDecl *NewVD); @@ -1418,6 +1484,7 @@ public: void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); void ActOnStartFunctionDeclarator(); void ActOnEndFunctionDeclarator(); + NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, TypeSourceInfo *TInfo, LookupResult &Previous, @@ -1429,12 +1496,17 @@ public: bool CheckConstexprFunctionDecl(const FunctionDecl *FD); bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body); - void DiagnoseHiddenVirtualMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); + void DiagnoseHiddenVirtualMethods(CXXMethodDecl *MD); + void FindHiddenVirtualMethods(CXXMethodDecl *MD, + SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods); + void NoteHiddenVirtualMethods(CXXMethodDecl *MD, + SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods); // Returns true if the function declaration is a redeclaration bool CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, LookupResult &Previous, bool IsExplicitSpecialization); void CheckMain(FunctionDecl *FD, const DeclSpec &D); + void CheckMSVCRTEntryPoint(FunctionDecl *FD); Decl *ActOnParamDeclarator(Scope *S, Declarator &D); ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, @@ -1462,19 +1534,20 @@ public: void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc); void FinalizeDeclaration(Decl *D); DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, - Decl **Group, - unsigned NumDecls); - DeclGroupPtrTy BuildDeclaratorGroup(Decl **Group, unsigned NumDecls, + ArrayRef<Decl *> Group); + DeclGroupPtrTy BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group, bool TypeMayContainAuto = true); /// Should be called on all declarations that might have attached /// documentation comments. void ActOnDocumentableDecl(Decl *D); - void ActOnDocumentableDecls(Decl **Group, unsigned NumDecls); + void ActOnDocumentableDecls(ArrayRef<Decl *> Group); void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, SourceLocation LocAfterDecls); - void CheckForFunctionRedefinition(FunctionDecl *FD); + void CheckForFunctionRedefinition(FunctionDecl *FD, + const FunctionDecl *EffectiveDefinition = + 0); Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D); Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D); void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); @@ -1533,6 +1606,10 @@ public: DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, ModuleIdPath Path); + /// \brief The parser has processed a module import translated from a + /// #include or similar preprocessing directive. + void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod); + /// \brief Create an implicit import of the given module at the given /// source location. /// @@ -1660,6 +1737,7 @@ public: /// member declarations. void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, SourceLocation FinalLoc, + bool IsFinalSpelledSealed, SourceLocation LBraceLoc); /// ActOnTagFinishDefinition - Invoked once we have finished parsing @@ -1748,7 +1826,7 @@ public: /// \param ExplicitInstantiationOrSpecialization When true, we are checking /// whether the declaration is in scope for the purposes of explicit template /// instantiation or specialization. The default is false. - bool isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S = 0, + bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = 0, bool ExplicitInstantiationOrSpecialization = false); /// Finds the scope corresponding to the given decl context, if it @@ -1780,9 +1858,9 @@ public: unsigned AttrSpellingListIndex); DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex); - FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, - int FormatIdx, int FirstArg, - unsigned AttrSpellingListIndex); + FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, + IdentifierInfo *Format, int FormatIdx, + int FirstArg, unsigned AttrSpellingListIndex); SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name, unsigned AttrSpellingListIndex); @@ -1802,13 +1880,13 @@ public: void mergeDeclAttributes(NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK = AMK_Redeclaration); void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls); - bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S); + bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S, + bool MergeTypeWithOld); bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, - Scope *S); + Scope *S, bool MergeTypeWithOld); void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old); - void MergeVarDecl(VarDecl *New, LookupResult &OldDecls, - bool OldDeclsWereHidden); - void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool OldIsHidden); + void MergeVarDecl(VarDecl *New, LookupResult &Previous); + void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld); void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old); bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S); @@ -1821,7 +1899,8 @@ public: AA_Converting, AA_Initializing, AA_Sending, - AA_Casting + AA_Casting, + AA_Passing_CFAudited }; /// C++ Overloading. @@ -1920,65 +1999,91 @@ public: /// Contexts in which a converted constant expression is required. enum CCEKind { - CCEK_CaseValue, ///< Expression in a case label. - CCEK_Enumerator, ///< Enumerator value with fixed underlying type. - CCEK_TemplateArg ///< Value of a non-type template parameter. + CCEK_CaseValue, ///< Expression in a case label. + CCEK_Enumerator, ///< Enumerator value with fixed underlying type. + CCEK_TemplateArg, ///< Value of a non-type template parameter. + CCEK_NewExpr ///< Constant expression in a noptr-new-declarator. }; ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE); - /// \brief Abstract base class used to diagnose problems that occur while - /// trying to convert an expression to integral or enumeration type. - class ICEConvertDiagnoser { + /// \brief Abstract base class used to perform a contextual implicit + /// conversion from an expression to any type passing a filter. + class ContextualImplicitConverter { public: bool Suppress; bool SuppressConversion; - ICEConvertDiagnoser(bool Suppress = false, - bool SuppressConversion = false) - : Suppress(Suppress), SuppressConversion(SuppressConversion) { } + ContextualImplicitConverter(bool Suppress = false, + bool SuppressConversion = false) + : Suppress(Suppress), SuppressConversion(SuppressConversion) {} + + /// \brief Determine whether the specified type is a valid destination type + /// for this conversion. + virtual bool match(QualType T) = 0; /// \brief Emits a diagnostic complaining that the expression does not have /// integral or enumeration type. - virtual DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, - QualType T) = 0; + virtual SemaDiagnosticBuilder + diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) = 0; /// \brief Emits a diagnostic when the expression has incomplete class type. - virtual DiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, - QualType T) = 0; + virtual SemaDiagnosticBuilder + diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) = 0; /// \brief Emits a diagnostic when the only matching conversion function /// is explicit. - virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, - QualType T, - QualType ConvTy) = 0; + virtual SemaDiagnosticBuilder diagnoseExplicitConv( + Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; /// \brief Emits a note for the explicit conversion function. - virtual DiagnosticBuilder + virtual SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; /// \brief Emits a diagnostic when there are multiple possible conversion /// functions. - virtual DiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, - QualType T) = 0; + virtual SemaDiagnosticBuilder + diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) = 0; /// \brief Emits a note for one of the candidate conversions. - virtual DiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, - QualType ConvTy) = 0; + virtual SemaDiagnosticBuilder + noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; /// \brief Emits a diagnostic when we picked a conversion function /// (for cases when we are not allowed to pick a conversion function). - virtual DiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, - QualType T, - QualType ConvTy) = 0; + virtual SemaDiagnosticBuilder diagnoseConversion( + Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; - virtual ~ICEConvertDiagnoser() {} + virtual ~ContextualImplicitConverter() {} }; - ExprResult - ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *FromE, - ICEConvertDiagnoser &Diagnoser, - bool AllowScopedEnumerations); + class ICEConvertDiagnoser : public ContextualImplicitConverter { + bool AllowScopedEnumerations; + + public: + ICEConvertDiagnoser(bool AllowScopedEnumerations, + bool Suppress, bool SuppressConversion) + : ContextualImplicitConverter(Suppress, SuppressConversion), + AllowScopedEnumerations(AllowScopedEnumerations) {} + + /// Match an integral or (possibly scoped) enumeration type. + bool match(QualType T); + + SemaDiagnosticBuilder + diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) { + return diagnoseNotInt(S, Loc, T); + } + + /// \brief Emits a diagnostic complaining that the expression does not have + /// integral or enumeration type. + virtual SemaDiagnosticBuilder + diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) = 0; + }; + + /// Perform a contextual implicit conversion. + ExprResult PerformContextualImplicitConversion( + SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter); + enum ObjCSubscriptKind { OS_Array, @@ -2054,12 +2159,14 @@ public: DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, Expr *From, QualType ToType, - OverloadCandidateSet& CandidateSet); + OverloadCandidateSet& CandidateSet, + bool AllowObjCConversionOnExplicit = false); void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, Expr *From, QualType ToType, - OverloadCandidateSet &CandidateSet); + OverloadCandidateSet &CandidateSet, + bool AllowObjCConversionOnExplicit = false); void AddSurrogateCandidate(CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, @@ -2159,14 +2266,13 @@ public: ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, - Expr **Args, unsigned NumArgs, + MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig, bool AllowTypoCorrection=true); bool buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, - Expr **Args, unsigned NumArgs, - SourceLocation RParenLoc, + MultiExprArg Args, SourceLocation RParenLoc, OverloadCandidateSet *CandidateSet, ExprResult *Result); @@ -2186,15 +2292,17 @@ public: ExprResult BuildCallToMemberFunction(Scope *S, Expr *MemExpr, - SourceLocation LParenLoc, Expr **Args, - unsigned NumArgs, SourceLocation RParenLoc); + SourceLocation LParenLoc, + MultiExprArg Args, + SourceLocation RParenLoc); ExprResult BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc, - Expr **Args, unsigned NumArgs, + MultiExprArg Args, SourceLocation RParenLoc); ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, - SourceLocation OpLoc); + SourceLocation OpLoc, + bool *NoArrowOperatorFound = 0); /// CheckCallReturnType - Checks that a call expression's return type is /// complete. Returns true on failure. The location passed in is the location @@ -2203,7 +2311,8 @@ public: CallExpr *CE, FunctionDecl *FD); /// Helpers for dealing with blocks and functions. - bool CheckParmsForFunctionDef(ParmVarDecl **Param, ParmVarDecl **ParamEnd, + bool CheckParmsForFunctionDef(ParmVarDecl *const *Param, + ParmVarDecl *const *ParamEnd, bool CheckParameterNames); void CheckCXXDefaultArguments(FunctionDecl *FD); void CheckExtraCXXDefaultArguments(Declarator &D); @@ -2271,6 +2380,9 @@ public: /// are outside of the current scope unless they have linkage. See /// C99 6.2.2p4-5 and C++ [basic.link]p6. LookupRedeclarationWithLinkage, + /// Look up a friend of a local class. This lookup does not look + /// outside the innermost non-class scope. See C++11 [class.friend]p11. + LookupLocalFriendName, /// Look up the name of an Objective-C protocol. LookupObjCProtocolName, /// Look up implicit 'self' parameter of an objective-c method. @@ -2303,7 +2415,11 @@ public: /// \brief The lookup found an overload set of literal operator templates, /// which expect the characters of the spelling of the literal token to be /// passed as a non-type template argument pack. - LOLR_Template + LOLR_Template, + /// \brief The lookup found an overload set of literal operator templates, + /// which expect the character type and characters of the spelling of the + /// string literal token to be passed as template arguments. + LOLR_StringTemplate }; SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D, @@ -2370,7 +2486,9 @@ public: LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R, ArrayRef<QualType> ArgTys, - bool AllowRawAndTemplate); + bool AllowRaw, + bool AllowTemplate, + bool AllowStringTemplate); bool isKnownName(StringRef name); void ArgumentDependentLookup(DeclarationName Name, bool Operator, @@ -2391,7 +2509,17 @@ public: CorrectionCandidateCallback &CCC, DeclContext *MemberContext = 0, bool EnteringContext = false, - const ObjCObjectPointerType *OPT = 0); + const ObjCObjectPointerType *OPT = 0, + bool RecordFailure = true); + + void diagnoseTypo(const TypoCorrection &Correction, + const PartialDiagnostic &TypoDiag, + bool ErrorRecovery = true); + + void diagnoseTypo(const TypoCorrection &Correction, + const PartialDiagnostic &TypoDiag, + const PartialDiagnostic &PrevNote, + bool ErrorRecovery = true); void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef<Expr *> Args, @@ -2402,7 +2530,7 @@ public: bool ConsiderLinkage, bool ExplicitInstantiationOrSpecialization); - bool DiagnoseAmbiguousLookup(LookupResult &Result); + void DiagnoseAmbiguousLookup(LookupResult &Result); //@} ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id, @@ -2419,12 +2547,8 @@ public: void ProcessPragmaWeak(Scope *S, Decl *D); // Decl attributes - this routine is the top level dispatcher. - void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, - bool NonInheritable = true, - bool Inheritable = true); + void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD); void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL, - bool NonInheritable = true, - bool Inheritable = true, bool IncludeCXX11Attributes = true); bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, const AttributeList *AttrList); @@ -2435,8 +2559,21 @@ public: bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, const FunctionDecl *FD = 0); bool CheckNoReturnAttr(const AttributeList &attr); + bool checkStringLiteralArgumentAttr(const AttributeList &Attr, + unsigned ArgNum, StringRef &Str, + SourceLocation *ArgLocation = 0); + void CheckAlignasUnderalignment(Decl *D); + /// Adjust the calling convention of a method to be the ABI default if it + /// wasn't specified explicitly. This handles method types formed from + /// function type typedefs and typename template arguments. + void adjustMemberFunctionCC(QualType &T, bool IsStatic); + + /// Get the outermost AttributedType node that sets a calling convention. + /// Valid types should not have multiple attributes with different CCs. + const AttributedType *getCallingConvAttributedType(QualType T) const; + /// \brief Stmt attributes - this routine is the top level dispatcher. StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs, SourceRange Range); @@ -2457,9 +2594,6 @@ public: ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl); - bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl, - ObjCInterfaceDecl *IDecl); - typedef llvm::SmallPtrSet<Selector, 8> SelectorSet; typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap; @@ -2507,6 +2641,16 @@ public: bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV); + /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which + /// backs the property is not used in the property's accessor. + void DiagnoseUnusedBackingIvarInAccessor(Scope *S); + + /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and + /// it property has a backing ivar, returns this ivar; otherwise, returns NULL. + /// It also returns ivar's property on success. + ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, + const ObjCPropertyDecl *&PDecl) const; + /// Called by ActOnProperty to handle \@property declarations in /// class extensions. ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S, @@ -2592,6 +2736,17 @@ private: bool receiverIdOrClass, bool warn, bool instance); + /// \brief Record the typo correction failure and return an empty correction. + TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc, + bool RecordFailure = true, + bool IsUnqualifiedLookup = false) { + if (IsUnqualifiedLookup) + (void)UnqualifiedTyposCorrected[Typo]; + if (RecordFailure) + TypoCorrectionFailures[Typo].insert(TypoLoc); + return TypoCorrection(); + } + public: /// AddInstanceMethodToGlobalPool - All instance methods in a translation /// unit are added to a global pool. This allows us to efficiently associate @@ -2628,6 +2783,14 @@ public: warn, /*instance*/false); } + const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel, + QualType ObjectType=QualType()); + + /// DiagnoseMismatchedMethodsInGlobalPool - This routine goes through list of + /// methods in global pool and issues diagnostic on identical selectors which + /// have mismathched types. + void DiagnoseMismatchedMethodsInGlobalPool(); + /// LookupImplementedMethodInGlobalPool - Returns the method which has an /// implementation. ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel); @@ -2691,8 +2854,7 @@ public: void ActOnStartOfCompoundStmt(); void ActOnFinishOfCompoundStmt(); StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, - MultiStmtArg Elts, - bool isStmtExpr); + ArrayRef<Stmt *> Elts, bool isStmtExpr); /// \brief A RAII object to enter scope of a compound statement. class CompoundScopeRAII { @@ -2865,11 +3027,10 @@ public: StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock); StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, - MultiStmtArg Handlers); + ArrayRef<Stmt *> Handlers); StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? - SourceLocation TryLoc, - Stmt *TryBlock, + SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler); StmtResult ActOnSEHExceptBlock(SourceLocation Loc, @@ -2944,7 +3105,7 @@ public: ObjCMethodDecl *Getter, SourceLocation Loc); void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, - Expr **Args, unsigned NumArgs); + ArrayRef<Expr *> Args); void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = 0, @@ -3006,12 +3167,19 @@ public: /// from within the current scope. Only valid when the variable can be /// captured. /// + /// \param FunctionScopeIndexToStopAt If non-null, it points to the index + /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. + /// This is useful when enclosing lambdas must speculatively capture + /// variables that may or may not be used in certain specializations of + /// a nested generic lambda. + /// /// \returns true if an error occurred (i.e., the variable cannot be /// captured) and false if the capture succeeded. bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, - QualType &DeclRefType); + QualType &DeclRefType, + const unsigned *const FunctionScopeIndexToStopAt); /// \brief Try to capture the given variable. bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, @@ -3034,8 +3202,8 @@ public: bool (*IsPlausibleResult)(QualType) = 0); /// \brief Figure out if an expression could be turned into a call. - bool isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, - UnresolvedSetImpl &NonTemplateOverloads); + bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, + UnresolvedSetImpl &NonTemplateOverloads); /// \brief Conditionally issue a diagnostic based on the current /// evaluation context. @@ -3054,7 +3222,8 @@ public: SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC = 0); + CorrectionCandidateCallback *CCC = 0, + bool IsInlineAsmIdentifier = false); void DecomposeUnqualifiedId(const UnqualifiedId &Id, TemplateArgumentListInfo &Buffer, @@ -3080,17 +3249,19 @@ public: ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS = 0); - ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, - ExprValueKind VK, + ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, const DeclarationNameInfo &NameInfo, - const CXXScopeSpec *SS = 0, - NamedDecl *FoundD = 0); + const CXXScopeSpec *SS = 0, NamedDecl *FoundD = 0, + const TemplateArgumentListInfo *TemplateArgs = 0); ExprResult - BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, - SourceLocation nameLoc, - IndirectFieldDecl *indirectField, - Expr *baseObjectExpr = 0, - SourceLocation opLoc = SourceLocation()); + BuildAnonymousStructUnionMemberReference( + const CXXScopeSpec &SS, + SourceLocation nameLoc, + IndirectFieldDecl *indirectField, + DeclAccessPair FoundDecl = DeclAccessPair::make(0, AS_none), + Expr *baseObjectExpr = 0, + SourceLocation opLoc = SourceLocation()); + ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, @@ -3115,9 +3286,9 @@ public: ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL); - ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, - const DeclarationNameInfo &NameInfo, - NamedDecl *D, NamedDecl *FoundD = 0); + ExprResult BuildDeclarationNameExpr( + const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, + NamedDecl *FoundD = 0, const TemplateArgumentListInfo *TemplateArgs = 0); ExprResult BuildLiteralOperatorCall(LookupResult &R, DeclarationNameInfo &SuffixInfo, @@ -3125,6 +3296,8 @@ public: SourceLocation LitEndLoc, TemplateArgumentListInfo *ExplicitTemplateArgs = 0); + ExprResult BuildPredefinedExpr(SourceLocation Loc, + PredefinedExpr::IdentType IT); ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = 0); @@ -3143,15 +3316,14 @@ public: SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, - MultiTypeArg ArgTypes, - MultiExprArg ArgExprs); + ArrayRef<ParsedType> ArgTypes, + ArrayRef<Expr *> ArgExprs); ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, - TypeSourceInfo **Types, - Expr **Exprs, - unsigned NumAssocs); + ArrayRef<TypeSourceInfo *> Types, + ArrayRef<Expr *> Exprs); // Binary/Unary Operators. 'Tok' is the token for the operator. ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, @@ -3161,6 +3333,8 @@ public: ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input); + QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc); + ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, @@ -3255,7 +3429,7 @@ public: bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, FunctionDecl *FDecl, const FunctionProtoType *Proto, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RParenLoc, bool ExecConfig = false); void CheckStaticArrayArgument(SourceLocation CallLoc, @@ -3270,7 +3444,7 @@ public: Expr *ExecConfig = 0, bool IsExecConfig = false); ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Arg, SourceLocation RParenLoc, Expr *Config = 0, bool IsExecConfig = false); @@ -3431,6 +3605,13 @@ public: ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, Scope *CurScope); + //===---------------------------- Clang Extensions ----------------------===// + + /// __builtin_convertvector(...) + ExprResult ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy, + SourceLocation BuiltinLoc, + SourceLocation RParenLoc); + //===---------------------------- OpenCL Features -----------------------===// /// __builtin_astype(...) @@ -3488,12 +3669,14 @@ public: void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow); bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target, - const LookupResult &PreviousDecls); + const LookupResult &PreviousDecls, + UsingShadowDecl *&PrevShadow); UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD, - NamedDecl *Target); + NamedDecl *Target, + UsingShadowDecl *PrevDecl); bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc, - bool isTypeName, + bool HasTypenameKeyword, const CXXScopeSpec &SS, SourceLocation NameLoc, const LookupResult &Previous); @@ -3507,7 +3690,7 @@ public: const DeclarationNameInfo &NameInfo, AttributeList *AttrList, bool IsInstantiation, - bool IsTypeName, + bool HasTypenameKeyword, SourceLocation TypenameLoc); bool CheckInheritingConstructorUsingDecl(UsingDecl *UD); @@ -3519,7 +3702,7 @@ public: CXXScopeSpec &SS, UnqualifiedId &Name, AttributeList *AttrList, - bool IsTypeName, + bool HasTypenameKeyword, SourceLocation TypenameLoc); Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, @@ -3918,7 +4101,17 @@ public: /// /// \param Explicit Whether 'this' is explicitly captured in a lambda /// capture list. - void CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false); + /// + /// \param FunctionScopeIndexToStopAt If non-null, it points to the index + /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. + /// This is useful when enclosing lambdas must speculatively capture + /// 'this' that may or may not be used in certain specializations of + /// a nested generic lambda (depending on whether the name resolves to + /// a non-static member function or a static function). + /// \return returns 'true' if failed, 'false' if success. + bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, + bool BuildAndDiagnose = true, + const unsigned *const FunctionScopeIndexToStopAt = 0); /// \brief Determine whether the given type is the type of *this that is used /// outside of the body of a member function for a type that is currently @@ -3979,22 +4172,26 @@ public: SourceRange R); bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, bool UseGlobal, QualType AllocType, bool IsArray, - Expr **PlaceArgs, unsigned NumPlaceArgs, + MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete); bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, - DeclarationName Name, Expr** Args, - unsigned NumArgs, DeclContext *Ctx, + DeclarationName Name, MultiExprArg Args, + DeclContext *Ctx, bool AllowMissing, FunctionDecl *&Operator, bool Diagnose = true); void DeclareGlobalNewDelete(); void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, - QualType Argument, + QualType Param1, + QualType Param2 = QualType(), bool addMallocAttr = false); bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl* &Operator, bool Diagnose = true); + FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc, + bool CanProvideSize, + DeclarationName Name); /// ActOnCXXDelete - Parsed a C++ 'delete' expression ExprResult ActOnCXXDelete(SourceLocation StartLoc, @@ -4120,7 +4317,8 @@ public: } ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC, bool DiscardedValue = false, - bool IsConstexpr = false); + bool IsConstexpr = false, + bool IsLambdaInitCaptureInitializer = false); StmtResult ActOnFinishFullStmt(Stmt *Stmt); // Marks SS invalid if it represents an incomplete type. @@ -4131,7 +4329,6 @@ public: bool EnteringContext = false); bool isDependentScopeSpecifier(const CXXScopeSpec &SS); CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS); - bool isUnknownSpecialization(const CXXScopeSpec &SS); /// \brief The parser has parsed a global nested-name-specifier '::'. /// @@ -4296,7 +4493,8 @@ public: /// \brief Create a new lambda closure type. CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange, TypeSourceInfo *Info, - bool KnownDependent); + bool KnownDependent, + LambdaCaptureDefault CaptureDefault); /// \brief Start the definition of a lambda expression. CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class, @@ -4305,13 +4503,31 @@ public: SourceLocation EndLoc, ArrayRef<ParmVarDecl *> Params); - /// \brief Introduce the scope for a lambda expression. - sema::LambdaScopeInfo *enterLambdaScope(CXXMethodDecl *CallOperator, - SourceRange IntroducerRange, - LambdaCaptureDefault CaptureDefault, - bool ExplicitParams, - bool ExplicitResultType, - bool Mutable); + /// \brief Endow the lambda scope info with the relevant properties. + void buildLambdaScope(sema::LambdaScopeInfo *LSI, + CXXMethodDecl *CallOperator, + SourceRange IntroducerRange, + LambdaCaptureDefault CaptureDefault, + SourceLocation CaptureDefaultLoc, + bool ExplicitParams, + bool ExplicitResultType, + bool Mutable); + + /// \brief Perform initialization analysis of the init-capture and perform + /// any implicit conversions such as an lvalue-to-rvalue conversion if + /// not being used to initialize a reference. + QualType performLambdaInitCaptureInitialization(SourceLocation Loc, + bool ByRef, IdentifierInfo *Id, Expr *&Init); + /// \brief Create a dummy variable within the declcontext of the lambda's + /// call operator, for name lookup purposes for a lambda init capture. + /// + /// CodeGen handles emission of lambda captures, ignoring these dummy + /// variables appropriately. + VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, + QualType InitCaptureType, IdentifierInfo *Id, Expr *Init); + + /// \brief Build the implicit field for an init-capture. + FieldDecl *buildInitCaptureField(sema::LambdaScopeInfo *LSI, VarDecl *Var); /// \brief Note that we have finished the explicit captures for the /// given lambda. @@ -4444,6 +4660,7 @@ public: // bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS = 0); + bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS); bool ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc, @@ -4466,7 +4683,7 @@ public: const DeclSpec &DS, SourceLocation IdLoc, SourceLocation LParenLoc, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RParenLoc, SourceLocation EllipsisLoc); @@ -4590,7 +4807,9 @@ public: void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record); void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnFinishDelayedMemberInitializers(Decl *Record); - void MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag = true); + void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD, + CachedTokens &Toks); + void UnmarkAsLateParsedTemplate(FunctionDecl *FD); bool IsInsideALocalClassWithinATemplateFunction(); Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, @@ -4624,7 +4843,7 @@ public: void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD); void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD, const FunctionProtoType *T); - void CheckDelayedExplicitlyDefaultedMemberExceptionSpecs(); + void CheckDelayedMemberExceptionSpecs(); //===--------------------------------------------------------------------===// // C++ Derived Classes @@ -4687,7 +4906,7 @@ public: bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange); /// CheckOverrideControl - Check C++11 override control semantics. - void CheckOverrideControl(Decl *D); + void CheckOverrideControl(NamedDecl *D); /// CheckForFunctionMarkedFinal - Checks whether a virtual member function /// overrides a virtual member function marked 'final', according to @@ -4735,6 +4954,9 @@ public: const PartialDiagnostic &PDiag, QualType objectType = QualType()); AccessResult CheckFriendAccess(NamedDecl *D); + AccessResult CheckMemberAccess(SourceLocation UseLoc, + CXXRecordDecl *NamingClass, + DeclAccessPair Found); AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, Expr *ArgExpr, @@ -4771,6 +4993,7 @@ public: AbstractVariableType, AbstractFieldType, AbstractIvarType, + AbstractSynthesizedIvarType, AbstractArrayType }; @@ -4878,12 +5101,13 @@ public: Decl **Params, unsigned NumParams, SourceLocation RAngleLoc); - /// \brief The context in which we are checking a template parameter - /// list. + /// \brief The context in which we are checking a template parameter list. enum TemplateParamListContext { TPC_ClassTemplate, + TPC_VarTemplate, TPC_FunctionTemplate, TPC_ClassTemplateMember, + TPC_FriendClassTemplate, TPC_FriendFunctionTemplate, TPC_FriendFunctionTemplateDefinition, TPC_TypeAliasTemplate @@ -4892,15 +5116,10 @@ public: bool CheckTemplateParameterList(TemplateParameterList *NewParams, TemplateParameterList *OldParams, TemplateParamListContext TPC); - TemplateParameterList * - MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, - SourceLocation DeclLoc, - const CXXScopeSpec &SS, - TemplateParameterList **ParamLists, - unsigned NumParamLists, - bool IsFriend, - bool &IsExplicitSpecialization, - bool &Invalid); + TemplateParameterList *MatchTemplateParametersToScopeSpecifier( + SourceLocation DeclStartLoc, SourceLocation DeclLoc, + const CXXScopeSpec &SS, ArrayRef<TemplateParameterList *> ParamLists, + bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid); DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, @@ -4942,6 +5161,21 @@ public: ASTTemplateArgsPtr TemplateArgsIn, SourceLocation RAngleLoc); + DeclResult ActOnVarTemplateSpecialization( + Scope *S, VarTemplateDecl *VarTemplate, Declarator &D, TypeSourceInfo *DI, + SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams, + StorageClass SC, bool IsPartialSpecialization); + + DeclResult CheckVarTemplateId(VarTemplateDecl *Template, + SourceLocation TemplateLoc, + SourceLocation TemplateNameLoc, + const TemplateArgumentListInfo &TemplateArgs); + + ExprResult CheckVarTemplateId(const CXXScopeSpec &SS, + const DeclarationNameInfo &NameInfo, + VarTemplateDecl *Template, + SourceLocation TemplateLoc, + const TemplateArgumentListInfo *TemplateArgs); ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, @@ -5035,7 +5269,9 @@ public: SourceLocation TemplateLoc, SourceLocation RAngleLoc, Decl *Param, - SmallVectorImpl<TemplateArgument> &Converted); + SmallVectorImpl<TemplateArgument> + &Converted, + bool &HasDefaultArg); /// \brief Specifies the context in which a particular template /// argument is being checked. @@ -5289,7 +5525,7 @@ public: /// \brief Block expression, UPPC_Block -}; + }; /// \brief Diagnose unexpanded parameter packs. /// @@ -5538,10 +5774,25 @@ public: /// false otherwise. bool containsUnexpandedParameterPacks(Declarator &D); + /// \brief Returns the pattern of the pack expansion for a template argument. + /// + /// \param OrigLoc The template argument to expand. + /// + /// \param Ellipsis Will be set to the location of the ellipsis. + /// + /// \param NumExpansions Will be set to the number of expansions that will + /// be generated from this pack expansion, if known a priori. + TemplateArgumentLoc getTemplateArgumentPackExpansionPattern( + TemplateArgumentLoc OrigLoc, + SourceLocation &Ellipsis, + Optional<unsigned> &NumExpansions) const; + //===--------------------------------------------------------------------===// // C++ Template Argument Deduction (C++ [temp.deduct]) //===--------------------------------------------------------------------===// + QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType); + /// \brief Describes the result of template argument deduction. /// /// The TemplateDeductionResult enumeration describes the result of @@ -5598,12 +5849,16 @@ public: sema::TemplateDeductionInfo &Info); TemplateDeductionResult - SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - TemplateArgumentListInfo &ExplicitTemplateArgs, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - SmallVectorImpl<QualType> &ParamTypes, - QualType *FunctionType, - sema::TemplateDeductionInfo &Info); + DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, + const TemplateArgumentList &TemplateArgs, + sema::TemplateDeductionInfo &Info); + + TemplateDeductionResult SubstituteExplicitTemplateArguments( + FunctionTemplateDecl *FunctionTemplate, + TemplateArgumentListInfo &ExplicitTemplateArgs, + SmallVectorImpl<DeducedTemplateArgument> &Deduced, + SmallVectorImpl<QualType> &ParamTypes, QualType *FunctionType, + sema::TemplateDeductionInfo &Info); /// brief A function argument from which we performed template argument // deduction for a call. @@ -5655,6 +5910,12 @@ public: sema::TemplateDeductionInfo &Info, bool InOverloadResolution = false); + /// \brief Substitute Replacement for \p auto in \p TypeWithAuto + QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement); + /// \brief Substitute Replacement for auto in TypeWithAuto + TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, + QualType Replacement); + /// \brief Result type of DeduceAutoType. enum DeduceAutoResult { DAR_Succeeded, @@ -5666,7 +5927,6 @@ public: QualType &Result); DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result); - QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement); void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init); bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose = true); @@ -5679,17 +5939,16 @@ public: FunctionTemplateDecl *FT2, SourceLocation Loc, TemplatePartialOrderingContext TPOC, - unsigned NumCallArguments); - UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin, - UnresolvedSetIterator SEnd, - TemplatePartialOrderingContext TPOC, - unsigned NumCallArguments, - SourceLocation Loc, - const PartialDiagnostic &NoneDiag, - const PartialDiagnostic &AmbigDiag, - const PartialDiagnostic &CandidateDiag, - bool Complain = true, - QualType TargetType = QualType()); + unsigned NumCallArguments1, + unsigned NumCallArguments2); + UnresolvedSetIterator + getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, + TemplateSpecCandidateSet &FailedCandidates, + SourceLocation Loc, + const PartialDiagnostic &NoneDiag, + const PartialDiagnostic &AmbigDiag, + const PartialDiagnostic &CandidateDiag, + bool Complain = true, QualType TargetType = QualType()); ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization( @@ -5697,6 +5956,10 @@ public: ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc); + VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization( + VarTemplatePartialSpecializationDecl *PS1, + VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc); + void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, bool OnlyDeduced, unsigned Depth, @@ -5814,10 +6077,7 @@ public: case PriorTemplateArgumentSubstitution: case DefaultTemplateArgumentChecking: - if (X.Template != Y.Template) - return false; - - // Fall through + return X.Template == Y.Template && X.TemplateArgs == Y.TemplateArgs; case DefaultTemplateArgumentInstantiation: case ExplicitTemplateArgumentSubstitution: @@ -5845,6 +6105,20 @@ public: SmallVector<ActiveTemplateInstantiation, 16> ActiveTemplateInstantiations; + /// \brief Extra modules inspected when performing a lookup during a template + /// instantiation. Computed lazily. + SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules; + + /// \brief Cache of additional modules that should be used for name lookup + /// within the current template instantiation. Computed lazily; use + /// getLookupModules() to get a complete set. + llvm::DenseSet<Module*> LookupModulesCache; + + /// \brief Get the set of additional modules that should be checked during + /// name lookup. A module and its imports become visible when instanting a + /// template defined within it. + llvm::DenseSet<Module*> &getLookupModules(); + /// \brief Whether we are in a SFINAE context that is not associated with /// template instantiation. /// @@ -5906,8 +6180,9 @@ public: /// deduction. /// /// FIXME: Serialize this structure to the AST file. - llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> > - SuppressedDiagnostics; + typedef llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> > + SuppressedDiagnosticsMap; + SuppressedDiagnosticsMap SuppressedDiagnostics; /// \brief A stack object to be created when performing template /// instantiation. @@ -5959,6 +6234,15 @@ public: sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); + /// \brief Note that we are instantiating as part of template + /// argument deduction for a variable template partial + /// specialization. + InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + VarTemplatePartialSpecializationDecl *PartialSpec, + ArrayRef<TemplateArgument> TemplateArgs, + sema::TemplateDeductionInfo &DeductionInfo, + SourceRange InstantiationRange = SourceRange()); + InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param, ArrayRef<TemplateArgument> TemplateArgs, @@ -5994,7 +6278,7 @@ public: /// \brief Determines whether we have exceeded the maximum /// recursive template instantiations. - operator bool() const { return Invalid; } + bool isInvalid() const { return Invalid; } private: Sema &SemaRef; @@ -6031,7 +6315,7 @@ public: /// \brief RAII class used to determine whether SFINAE has /// trapped any errors that occur during template argument - /// deduction.` + /// deduction. class SFINAETrap { Sema &SemaRef; unsigned PrevSFINAEErrors; @@ -6063,10 +6347,34 @@ public: } }; + /// \brief RAII class used to indicate that we are performing provisional + /// semantic analysis to determine the validity of a construct, so + /// typo-correction and diagnostics in the immediate context (not within + /// implicitly-instantiated templates) should be suppressed. + class TentativeAnalysisScope { + Sema &SemaRef; + // FIXME: Using a SFINAETrap for this is a hack. + SFINAETrap Trap; + bool PrevDisableTypoCorrection; + public: + explicit TentativeAnalysisScope(Sema &SemaRef) + : SemaRef(SemaRef), Trap(SemaRef, true), + PrevDisableTypoCorrection(SemaRef.DisableTypoCorrection) { + SemaRef.DisableTypoCorrection = true; + } + ~TentativeAnalysisScope() { + SemaRef.DisableTypoCorrection = PrevDisableTypoCorrection; + } + }; + /// \brief The current instantiation scope used to store local /// variables. LocalInstantiationScope *CurrentInstantiationScope; + /// \brief Tracks whether we are in a context where typo correction is + /// disabled. + bool DisableTypoCorrection; + /// \brief The number of typos corrected by CorrectTypo. unsigned TyposCorrected; @@ -6081,6 +6389,14 @@ public: /// string represents a keyword. UnqualifiedTyposCorrectedMap UnqualifiedTyposCorrected; + typedef llvm::SmallSet<SourceLocation, 2> SrcLocSet; + typedef llvm::DenseMap<IdentifierInfo *, SrcLocSet> IdentifierSourceLocations; + + /// \brief A cache containing identifiers for which typo correction failed and + /// their locations, so that repeated attempts to correct an identifier in a + /// given location are ignored if typo correction already failed for it. + IdentifierSourceLocations TypoCorrectionFailures; + /// \brief Worker object for performing CFG-based warnings. sema::AnalysisBasedWarnings AnalysisWarnings; @@ -6107,6 +6423,26 @@ public: /// types, static variables, enumerators, etc. std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations; + class SavePendingLocalImplicitInstantiationsRAII { + public: + SavePendingLocalImplicitInstantiationsRAII(Sema &S): S(S) { + SavedPendingLocalImplicitInstantiations.swap( + S.PendingLocalImplicitInstantiations); + } + + ~SavePendingLocalImplicitInstantiationsRAII() { + assert(S.PendingLocalImplicitInstantiations.empty() && + "there shouldn't be any pending local implicit instantiations"); + SavedPendingLocalImplicitInstantiations.swap( + S.PendingLocalImplicitInstantiations); + } + + private: + Sema &S; + std::deque<PendingImplicitInstantiation> + SavedPendingLocalImplicitInstantiations; + }; + void PerformPendingInstantiations(bool LocalOnly = false); TypeSourceInfo *SubstType(TypeSourceInfo *T, @@ -6240,6 +6576,30 @@ public: FunctionDecl *Function, bool Recursive = false, bool DefinitionRequired = false); + VarTemplateSpecializationDecl *BuildVarTemplateInstantiation( + VarTemplateDecl *VarTemplate, VarDecl *FromVar, + const TemplateArgumentList &TemplateArgList, + const TemplateArgumentListInfo &TemplateArgsInfo, + SmallVectorImpl<TemplateArgument> &Converted, + SourceLocation PointOfInstantiation, void *InsertPos, + LateInstantiatedAttrVec *LateAttrs = 0, + LocalInstantiationScope *StartingScope = 0); + VarTemplateSpecializationDecl *CompleteVarTemplateSpecializationDecl( + VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl, + const MultiLevelTemplateArgumentList &TemplateArgs); + void + BuildVariableInstantiation(VarDecl *NewVar, VarDecl *OldVar, + const MultiLevelTemplateArgumentList &TemplateArgs, + LateInstantiatedAttrVec *LateAttrs, + DeclContext *Owner, + LocalInstantiationScope *StartingScope, + bool InstantiatingVarTemplate = false); + void InstantiateVariableInitializer( + VarDecl *Var, VarDecl *OldVar, + const MultiLevelTemplateArgumentList &TemplateArgs); + void InstantiateVariableDefinition(SourceLocation PointOfInstantiation, + VarDecl *Var, bool Recursive = false, + bool DefinitionRequired = false); void InstantiateStaticDataMemberDefinition( SourceLocation PointOfInstantiation, VarDecl *Var, @@ -6277,6 +6637,10 @@ public: const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList); + + void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, + IdentifierInfo *SuperName, + SourceLocation SuperLoc); Decl *ActOnCompatibilityAlias( SourceLocation AtCompatibilityAliasLoc, @@ -6359,18 +6723,15 @@ public: void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, - const IdentifierInfo *Name); + const IdentifierInfo *Name, + bool OverridingProtocolProperty); void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, ObjCInterfaceDecl *ID); - void MatchOneProtocolPropertiesInClass(Decl *CDecl, - ObjCProtocolDecl *PDecl); - Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd, - Decl **allMethods = 0, unsigned allNum = 0, - Decl **allProperties = 0, unsigned pNum = 0, - DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0); + ArrayRef<Decl *> allMethods = None, + ArrayRef<DeclGroupPtrTy> allTUVars = None); Decl *ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, @@ -6584,6 +6945,15 @@ public: PMSST_ON // #pragms ms_struct on }; + enum PragmaMSCommentKind { + PCK_Unknown, + PCK_Linker, // #pragma comment(linker, ...) + PCK_Lib, // #pragma comment(lib, ...) + PCK_Compiler, // #pragma comment(compiler, ...) + PCK_ExeStr, // #pragma comment(exestr, ...) + PCK_User // #pragma comment(user, ...) + }; + /// ActOnPragmaPack - Called on well formed \#pragma pack(...). void ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, @@ -6595,6 +6965,13 @@ public: /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off]. void ActOnPragmaMSStruct(PragmaMSStructKind Kind); + /// ActOnPragmaMSComment - Called on well formed + /// \#pragma comment(kind, "arg"). + void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg); + + /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch + void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value); + /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'. void ActOnPragmaUnused(const Token &Identifier, Scope *curScope, @@ -6670,16 +7047,79 @@ public: unsigned SpellingListIndex, bool IsPackExpansion); // OpenMP directives and clauses. +private: + void *VarDataSharingAttributesStack; + /// \brief Initialization of data-sharing attributes stack. + void InitDataSharingAttributesStack(); + void DestroyDataSharingAttributesStack(); +public: + /// \brief Called on start of new data sharing attribute block. + void StartOpenMPDSABlock(OpenMPDirectiveKind K, + const DeclarationNameInfo &DirName, + Scope *CurScope); + /// \brief Called on end of data sharing attribute block. + void EndOpenMPDSABlock(Stmt *CurDirective); + // OpenMP directives and clauses. + /// \brief Called on correct id-expression from the '#pragma omp + /// threadprivate'. + ExprResult ActOnOpenMPIdExpression(Scope *CurScope, + CXXScopeSpec &ScopeSpec, + const DeclarationNameInfo &Id); /// \brief Called on well-formed '#pragma omp threadprivate'. DeclGroupPtrTy ActOnOpenMPThreadprivateDirective( - SourceLocation Loc, - Scope *CurScope, - ArrayRef<DeclarationNameInfo> IdList); - /// \brief Build a new OpenMPThreadPrivateDecl and check its correctness. + SourceLocation Loc, + ArrayRef<Expr *> VarList); + // \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness. OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl( - SourceLocation Loc, - ArrayRef<DeclRefExpr *> VarList); + SourceLocation Loc, + ArrayRef<Expr *> VarList); + + StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, + ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp parallel' after parsing + /// of the associated statement. + StmtResult ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc); + + OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, + unsigned Argument, + SourceLocation ArgumentLoc, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'default' clause. + OMPClause *ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, + SourceLocation KindLoc, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + + OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind, + ArrayRef<Expr *> Vars, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'private' clause. + OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'firstprivate' clause. + OMPClause *ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'shared' clause. + OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// \brief The kind of conversion being performed. enum CheckedConversionKind { @@ -6753,20 +7193,25 @@ public: enum VarArgKind { VAK_Valid, VAK_ValidInCXX11, + VAK_Undefined, VAK_Invalid }; // Determines which VarArgKind fits an expression. VarArgKind isValidVarArgType(const QualType &Ty); + /// Check to see if the given expression is a valid argument to a variadic + /// function, issuing a diagnostic if not. + void checkVariadicArgument(const Expr *E, VariadicCallType CT); + /// GatherArgumentsForCall - Collector argument expressions for various /// form of call prototypes. bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, const FunctionProtoType *Proto, unsigned FirstProtoArg, - Expr **Args, unsigned NumArgs, - SmallVector<Expr *, 8> &AllArgs, + ArrayRef<Expr *> Args, + SmallVectorImpl<Expr *> &AllArgs, VariadicCallType CallType = VariadicDoesNotApply, bool AllowExplicit = false, bool IsListInitialization = false); @@ -6776,10 +7221,6 @@ public: ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl); - /// Checks to see if the given expression is a valid argument to a variadic - /// function, issuing a diagnostic and returning NULL if not. - bool variadicArgumentPODCheck(const Expr *E, VariadicCallType CT); - // UsualArithmeticConversions - performs the UsualUnaryConversions on it's // operands and then handles various conversions that are common to binary // operators (C99 6.3.1.8). If both operands aren't arithmetic, this @@ -6892,7 +7333,8 @@ public: // this routine performs the default function/array converions. AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, - bool Diagnose = true); + bool Diagnose = true, + bool DiagnoseCFAudited = false); // \brief If the lhs type is a transparent union, check whether we // can initialize the transparent union with the given expression. @@ -7071,7 +7513,8 @@ public: /// retainable pointers and other pointer kinds. ARCConversionResult CheckObjCARCConversion(SourceRange castRange, QualType castType, Expr *&op, - CheckedConversionKind CCK); + CheckedConversionKind CCK, + bool DiagnoseCFAudited = false); Expr *stripARCUnbridgedCast(Expr *e); void diagnoseARCUnbridgedCast(Expr *e); @@ -7098,7 +7541,7 @@ public: /// \param [out] ReturnType - The return type of the send. /// \return true iff there were any incompatible types. bool CheckMessageArgumentTypes(QualType ReceiverType, - Expr **Args, unsigned NumArgs, Selector Sel, + MultiExprArg Args, Selector Sel, ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, @@ -7186,8 +7629,8 @@ public: /// Returns false on success. /// Can optionally return whether the bit-field is of width 0 ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, - QualType FieldTy, Expr *BitWidth, - bool *ZeroWidth = 0); + QualType FieldTy, bool IsMsStruct, + Expr *BitWidth, bool *ZeroWidth = 0); enum CUDAFunctionTarget { CFT_Device, @@ -7284,9 +7727,10 @@ public: void CodeCompleteNamespaceDecl(Scope *S); void CodeCompleteNamespaceAliasDecl(Scope *S); void CodeCompleteOperatorName(Scope *S); - void CodeCompleteConstructorInitializer(Decl *Constructor, - CXXCtorInitializer** Initializers, - unsigned NumInitializers); + void CodeCompleteConstructorInitializer( + Decl *Constructor, + ArrayRef<CXXCtorInitializer *> Initializers); + void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, bool AfterAmpersand); @@ -7301,24 +7745,20 @@ public: bool IsParameter); void CodeCompleteObjCMessageReceiver(Scope *S); void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, - IdentifierInfo **SelIdents, - unsigned NumSelIdents, + ArrayRef<IdentifierInfo *> SelIdents, bool AtArgumentExpression); void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, - IdentifierInfo **SelIdents, - unsigned NumSelIdents, + ArrayRef<IdentifierInfo *> SelIdents, bool AtArgumentExpression, bool IsSuper = false); void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, - IdentifierInfo **SelIdents, - unsigned NumSelIdents, + ArrayRef<IdentifierInfo *> SelIdents, bool AtArgumentExpression, ObjCInterfaceDecl *Super = 0); void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar); void CodeCompleteObjCSelector(Scope *S, - IdentifierInfo **SelIdents, - unsigned NumSelIdents); + ArrayRef<IdentifierInfo *> SelIdents); void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols, unsigned NumProtocols); void CodeCompleteObjCProtocolDecl(Scope *S); @@ -7343,8 +7783,7 @@ public: bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnType, - IdentifierInfo **SelIdents, - unsigned NumSelIdents); + ArrayRef<IdentifierInfo *> SelIdents); void CodeCompletePreprocessorDirective(bool InConditional); void CodeCompleteInPreprocessorConditionalExclusion(Scope *S); void CodeCompletePreprocessorMacroName(bool IsDefinition); @@ -7385,8 +7824,9 @@ private: const FunctionProtoType *Proto); bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef<const Expr *> Args); - bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall, - const FunctionProtoType *Proto); + bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, + const FunctionProtoType *Proto); + bool CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto); void CheckConstructorCall(FunctionDecl *FDecl, ArrayRef<const Expr *> Args, const FunctionProtoType *Proto, @@ -7401,7 +7841,10 @@ private: bool CheckObjCString(Expr *Arg); ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + + bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool SemaBuiltinVAStart(CallExpr *TheCall); @@ -7411,6 +7854,9 @@ private: public: // Used by C++ template instantiation. ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall); + ExprResult SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, + SourceLocation BuiltinLoc, + SourceLocation RParenLoc); private: bool SemaBuiltinPrefetch(CallExpr *TheCall); @@ -7422,6 +7868,7 @@ private: bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result); +public: enum FormatStringType { FST_Scanf, FST_Printf, @@ -7433,37 +7880,26 @@ private: }; static FormatStringType GetFormatStringType(const FormatAttr *Format); - enum StringLiteralCheckType { - SLCT_NotALiteral, - SLCT_UncheckedLiteral, - SLCT_CheckedLiteral - }; - - StringLiteralCheckType checkFormatStringExpr(const Expr *E, - ArrayRef<const Expr *> Args, - bool HasVAListArg, - unsigned format_idx, - unsigned firstDataArg, - FormatStringType Type, - VariadicCallType CallType, - bool inFunctionCall = true); - void CheckFormatString(const StringLiteral *FExpr, const Expr *OrigFormatExpr, ArrayRef<const Expr *> Args, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, - VariadicCallType CallType); + VariadicCallType CallType, + llvm::SmallBitVector &CheckedVarArgs); +private: bool CheckFormatArguments(const FormatAttr *Format, ArrayRef<const Expr *> Args, bool IsCXXMember, VariadicCallType CallType, - SourceLocation Loc, SourceRange Range); + SourceLocation Loc, SourceRange Range, + llvm::SmallBitVector &CheckedVarArgs); bool CheckFormatArguments(ArrayRef<const Expr *> Args, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, - SourceLocation Loc, SourceRange range); + SourceLocation Loc, SourceRange range, + llvm::SmallBitVector &CheckedVarArgs); void CheckNonNullArguments(const NonNullAttr *NonNull, const Expr * const *ExprArgs, @@ -7536,6 +7972,7 @@ private: Scope *CurScope; mutable IdentifierInfo *Ident_super; + mutable IdentifierInfo *Ident___float128; protected: friend class Parser; @@ -7555,6 +7992,7 @@ public: Scope *getCurScope() const { return CurScope; } IdentifierInfo *getSuperIdentifier() const; + IdentifierInfo *getFloat128Identifier() const; Decl *getObjCDeclContext() const; @@ -7601,6 +8039,18 @@ public: } }; -} // end namespace clang +DeductionFailureInfo +MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK, + sema::TemplateDeductionInfo &Info); + +/// \brief Contains a late templated function. +/// Will be parsed at the end of the translation unit, used by Sema & Parser. +struct LateParsedTemplate { + CachedTokens Toks; + /// \brief The template function declaration to be late parsed. + Decl *D; +}; + +} // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h index 9605bf8..fdf9593 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/SemaDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define SEMASTART #include "clang/Basic/DiagnosticSemaKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/Sema/SemaInternal.h b/contrib/llvm/tools/clang/include/clang/Sema/SemaInternal.h index bbf4272..01d4cc9 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/SemaInternal.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/SemaInternal.h @@ -24,7 +24,44 @@ namespace clang { inline PartialDiagnostic Sema::PDiag(unsigned DiagID) { return PartialDiagnostic(DiagID, Context.getDiagAllocator()); } - +
+
+// This requires the variable to be non-dependent and the initializer
+// to not be value dependent.
+inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) {
+ const VarDecl *DefVD = 0;
+ return !isa<ParmVarDecl>(Var) &&
+ Var->isUsableInConstantExpressions(Context) &&
+ Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE();
+}
+
+// Directly mark a variable odr-used. Given a choice, prefer to use
+// MarkVariableReferenced since it does additional checks and then
+// calls MarkVarDeclODRUsed.
+// If the variable must be captured:
+// - if FunctionScopeIndexToStopAt is null, capture it in the CurContext
+// - else capture it in the DeclContext that maps to the
+// *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.
+inline void MarkVarDeclODRUsed(VarDecl *Var,
+ SourceLocation Loc, Sema &SemaRef,
+ const unsigned *const FunctionScopeIndexToStopAt) {
+ // Keep track of used but undefined variables.
+ // FIXME: We shouldn't suppress this warning for static data members.
+ if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
+ !Var->isExternallyVisible() &&
+ !(Var->isStaticDataMember() && Var->hasInit())) {
+ SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
+ if (old.isInvalid()) old = Loc;
+ }
+ QualType CaptureType, DeclRefType;
+ SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit,
+ /*EllipsisLoc*/ SourceLocation(),
+ /*BuildAndDiagnose*/ true,
+ CaptureType, DeclRefType,
+ FunctionScopeIndexToStopAt);
+
+ Var->markUsed(SemaRef.Context);
+} } #endif diff --git a/contrib/llvm/tools/clang/include/clang/Sema/SemaLambda.h b/contrib/llvm/tools/clang/include/clang/Sema/SemaLambda.h new file mode 100644 index 0000000..cf9fff1 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Sema/SemaLambda.h @@ -0,0 +1,39 @@ +//===--- SemaLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file provides some common utility functions for processing
+/// Lambdas.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_LAMBDA_H
+#define LLVM_CLANG_SEMA_LAMBDA_H
+#include "clang/AST/ASTLambda.h"
+#include "clang/Sema/ScopeInfo.h"
+namespace clang {
+
+// Given a lambda's call operator and a variable (or null for 'this'),
+// compute the nearest enclosing lambda that is capture-ready (i.e
+// the enclosing context is not dependent, and all intervening lambdas can
+// either implicitly or explicitly capture Var)
+//
+// Return the CallOperator of the capturable lambda and set function scope
+// index to the correct index within the function scope stack to correspond
+// to the capturable lambda.
+// If VarDecl *VD is null, we check for 'this' capture.
+CXXMethodDecl*
+GetInnermostEnclosingCapturableLambda(
+ ArrayRef<sema::FunctionScopeInfo*> FunctionScopes,
+ unsigned &FunctionScopeIndex,
+ DeclContext *const CurContext, VarDecl *VD, Sema &S);
+
+} // clang
+
+#endif // LLVM_CLANG_SEMA_LAMBDA_H
diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Template.h b/contrib/llvm/tools/clang/include/clang/Sema/Template.h index f9481c6..1af61d5 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Template.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Template.h @@ -97,13 +97,6 @@ namespace clang { addOuterTemplateArguments(ArgList(TemplateArgs->data(), TemplateArgs->size())); } - - /// \brief Add a new outmost level to the multi-level template argument - /// list. - void addOuterTemplateArguments(const TemplateArgument *Args, - unsigned NumArgs) { - addOuterTemplateArguments(ArgList(Args, NumArgs)); - } /// \brief Add a new outmost level to the multi-level template argument /// list. @@ -385,6 +378,14 @@ namespace clang { ClassTemplatePartialSpecializationDecl *>, 4> OutOfLinePartialSpecs; + /// \brief A list of out-of-line variable template partial + /// specializations that will need to be instantiated after the + /// enclosing variable's instantiation is complete. + /// FIXME: Verify that this is needed. + SmallVector< + std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4> + OutOfLineVarPartialSpecs; + public: TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs) @@ -393,62 +394,39 @@ namespace clang { Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0) { } - // FIXME: Once we get closer to completion, replace these manually-written - // declarations with automatically-generated ones from - // clang/AST/DeclNodes.inc. - Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); - Decl *VisitLabelDecl(LabelDecl *D); - Decl *VisitNamespaceDecl(NamespaceDecl *D); - Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); - Decl *VisitTypedefDecl(TypedefDecl *D); - Decl *VisitTypeAliasDecl(TypeAliasDecl *D); - Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); - Decl *VisitVarDecl(VarDecl *D); - Decl *VisitAccessSpecDecl(AccessSpecDecl *D); - Decl *VisitFieldDecl(FieldDecl *D); - Decl *VisitMSPropertyDecl(MSPropertyDecl *D); - Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D); - Decl *VisitStaticAssertDecl(StaticAssertDecl *D); - Decl *VisitEnumDecl(EnumDecl *D); - Decl *VisitEnumConstantDecl(EnumConstantDecl *D); - Decl *VisitFriendDecl(FriendDecl *D); - Decl *VisitFunctionDecl(FunctionDecl *D, - TemplateParameterList *TemplateParams = 0); - Decl *VisitCXXRecordDecl(CXXRecordDecl *D); +// Define all the decl visitors using DeclNodes.inc +#define DECL(DERIVED, BASE) \ + Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); +#define ABSTRACT_DECL(DECL) + +// Decls which never appear inside a class or function. +#define OBJCCONTAINER(DERIVED, BASE) +#define FILESCOPEASM(DERIVED, BASE) +#define IMPORT(DERIVED, BASE) +#define LINKAGESPEC(DERIVED, BASE) +#define OBJCCOMPATIBLEALIAS(DERIVED, BASE) +#define OBJCMETHOD(DERIVED, BASE) +#define OBJCIVAR(DERIVED, BASE) +#define OBJCPROPERTY(DERIVED, BASE) +#define OBJCPROPERTYIMPL(DERIVED, BASE) +#define EMPTY(DERIVED, BASE) + +// Decls which use special-case instantiation code. +#define BLOCK(DERIVED, BASE) +#define CAPTURED(DERIVED, BASE) +#define IMPLICITPARAM(DERIVED, BASE) + +#include "clang/AST/DeclNodes.inc" + + // A few supplemental visitor functions. Decl *VisitCXXMethodDecl(CXXMethodDecl *D, - TemplateParameterList *TemplateParams = 0, + TemplateParameterList *TemplateParams, bool IsClassScopeSpecialization = false); - Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D); - Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); - Decl *VisitCXXConversionDecl(CXXConversionDecl *D); - ParmVarDecl *VisitParmVarDecl(ParmVarDecl *D); - Decl *VisitClassTemplateDecl(ClassTemplateDecl *D); - Decl *VisitClassTemplatePartialSpecializationDecl( - ClassTemplatePartialSpecializationDecl *D); - Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); - Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); - Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); - Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); - Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); - Decl *VisitUsingDecl(UsingDecl *D); - Decl *VisitUsingShadowDecl(UsingShadowDecl *D); - Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); - Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); - Decl *VisitClassScopeFunctionSpecializationDecl( - ClassScopeFunctionSpecializationDecl *D); - Decl *VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); - - // Base case. FIXME: Remove once we can instantiate everything. - Decl *VisitDecl(Decl *D) { - unsigned DiagID = SemaRef.getDiagnostics().getCustomDiagID( - DiagnosticsEngine::Error, - "cannot instantiate %0 yet"); - SemaRef.Diag(D->getLocation(), DiagID) - << D->getDeclKindName(); - - return 0; - } - + Decl *VisitFunctionDecl(FunctionDecl *D, + TemplateParameterList *TemplateParams); + Decl *VisitDecl(Decl *D); + Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate); + // Enable late instantiation of attributes. Late instantiated attributes // will be stored in LA. void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { @@ -470,6 +448,10 @@ namespace clang { ::iterator delayed_partial_spec_iterator; + typedef SmallVectorImpl<std::pair< + VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator + delayed_var_partial_spec_iterator; + /// \brief Return an iterator to the beginning of the set of /// "delayed" partial specializations, which must be passed to /// InstantiateClassTemplatePartialSpecialization once the class @@ -478,6 +460,10 @@ namespace clang { return OutOfLinePartialSpecs.begin(); } + delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { + return OutOfLineVarPartialSpecs.begin(); + } + /// \brief Return an iterator to the end of the set of /// "delayed" partial specializations, which must be passed to /// InstantiateClassTemplatePartialSpecialization once the class @@ -486,6 +472,10 @@ namespace clang { return OutOfLinePartialSpecs.end(); } + delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { + return OutOfLineVarPartialSpecs.end(); + } + // Helper functions for instantiating methods. TypeSourceInfo *SubstFunctionType(FunctionDecl *D, SmallVectorImpl<ParmVarDecl *> &Params); @@ -499,12 +489,21 @@ namespace clang { DeclaratorDecl *NewDecl); bool SubstQualifier(const TagDecl *OldDecl, TagDecl *NewDecl); - + + Decl *VisitVarTemplateSpecializationDecl( + VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos, + const TemplateArgumentListInfo &TemplateArgsInfo, + llvm::ArrayRef<TemplateArgument> Converted); + Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); ClassTemplatePartialSpecializationDecl * InstantiateClassTemplatePartialSpecialization( ClassTemplateDecl *ClassTemplate, ClassTemplatePartialSpecializationDecl *PartialSpec); + VarTemplatePartialSpecializationDecl * + InstantiateVarTemplatePartialSpecialization( + VarTemplateDecl *VarTemplate, + VarTemplatePartialSpecializationDecl *PartialSpec); void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); }; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h b/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h index 8292045..1daa689 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h @@ -20,6 +20,7 @@ namespace clang { class TemplateArgumentList; +class Sema; namespace sema { @@ -162,7 +163,124 @@ public: Expr *Expression; }; -} -} +} // end namespace sema + +/// A structure used to record information about a failed +/// template argument deduction, for diagnosis. +struct DeductionFailureInfo { + /// A Sema::TemplateDeductionResult. + unsigned Result : 8; + + /// \brief Indicates whether a diagnostic is stored in Diagnostic. + unsigned HasDiagnostic : 1; + + /// \brief Opaque pointer containing additional data about + /// this deduction failure. + void *Data; + + /// \brief A diagnostic indicating why deduction failed. + union { + void *Align; + char Diagnostic[sizeof(PartialDiagnosticAt)]; + }; + + /// \brief Retrieve the diagnostic which caused this deduction failure, + /// if any. + PartialDiagnosticAt *getSFINAEDiagnostic(); + + /// \brief Retrieve the template parameter this deduction failure + /// refers to, if any. + TemplateParameter getTemplateParameter(); + + /// \brief Retrieve the template argument list associated with this + /// deduction failure, if any. + TemplateArgumentList *getTemplateArgumentList(); + + /// \brief Return the first template argument this deduction failure + /// refers to, if any. + const TemplateArgument *getFirstArg(); + + /// \brief Return the second template argument this deduction failure + /// refers to, if any. + const TemplateArgument *getSecondArg(); + + /// \brief Return the expression this deduction failure refers to, + /// if any. + Expr *getExpr(); + + /// \brief Free any memory associated with this deduction failure. + void Destroy(); +}; + +/// TemplateSpecCandidate - This is a generalization of OverloadCandidate +/// which keeps track of template argument deduction failure info, when +/// handling explicit specializations (and instantiations) of templates +/// beyond function overloading. +/// For now, assume that the candidates are non-matching specializations. +/// TODO: In the future, we may need to unify/generalize this with +/// OverloadCandidate. +struct TemplateSpecCandidate { + /// Specialization - The actual specialization that this candidate + /// represents. When NULL, this may be a built-in candidate. + Decl *Specialization; + + /// Template argument deduction info + DeductionFailureInfo DeductionFailure; + + void set(Decl *Spec, DeductionFailureInfo Info) { + Specialization = Spec; + DeductionFailure = Info; + } + + /// Diagnose a template argument deduction failure. + void NoteDeductionFailure(Sema &S); +}; + +/// TemplateSpecCandidateSet - A set of generalized overload candidates, +/// used in template specializations. +/// TODO: In the future, we may need to unify/generalize this with +/// OverloadCandidateSet. +class TemplateSpecCandidateSet { + SmallVector<TemplateSpecCandidate, 16> Candidates; + SourceLocation Loc; + + TemplateSpecCandidateSet( + const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; + void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; + + void destroyCandidates(); + +public: + TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {} + ~TemplateSpecCandidateSet() { destroyCandidates(); } + + SourceLocation getLocation() const { return Loc; } + + /// \brief Clear out all of the candidates. + /// TODO: This may be unnecessary. + void clear(); + + typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator; + iterator begin() { return Candidates.begin(); } + iterator end() { return Candidates.end(); } + + size_t size() const { return Candidates.size(); } + bool empty() const { return Candidates.empty(); } + + /// \brief Add a new candidate with NumConversions conversion sequence slots + /// to the overload set. + TemplateSpecCandidate &addCandidate() { + Candidates.push_back(TemplateSpecCandidate()); + return Candidates.back(); + } + + void NoteCandidates(Sema &S, SourceLocation Loc); + + void NoteCandidates(Sema &S, SourceLocation Loc) const { + const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc); + } +}; + +} // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h b/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h index cdd71c8..f0b7726 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h @@ -39,31 +39,35 @@ public: static const unsigned CallbackDistanceWeight = 150U; TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl, - NestedNameSpecifier *NNS=0, unsigned CharDistance=0, - unsigned QualifierDistance=0) + NestedNameSpecifier *NNS = 0, unsigned CharDistance = 0, + unsigned QualifierDistance = 0) : CorrectionName(Name), CorrectionNameSpec(NNS), - CharDistance(CharDistance), QualifierDistance(QualifierDistance), - CallbackDistance(0) { + CharDistance(CharDistance), QualifierDistance(QualifierDistance), + CallbackDistance(0), ForceSpecifierReplacement(false), + RequiresImport(false) { if (NameDecl) CorrectionDecls.push_back(NameDecl); } - TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS=0, - unsigned CharDistance=0) + TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = 0, + unsigned CharDistance = 0) : CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS), - CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0) { + CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0), + ForceSpecifierReplacement(false), RequiresImport(false) { if (Name) CorrectionDecls.push_back(Name); } - TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS=0, - unsigned CharDistance=0) + TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = 0, + unsigned CharDistance = 0) : CorrectionName(Name), CorrectionNameSpec(NNS), - CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0) {} + CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0), + ForceSpecifierReplacement(false), RequiresImport(false) {} TypoCorrection() : CorrectionNameSpec(0), CharDistance(0), QualifierDistance(0), - CallbackDistance(0) {} + CallbackDistance(0), ForceSpecifierReplacement(false), + RequiresImport(false) {} /// \brief Gets the DeclarationName of the typo correction DeclarationName getCorrection() const { return CorrectionName; } @@ -77,6 +81,15 @@ public: } void setCorrectionSpecifier(NestedNameSpecifier* NNS) { CorrectionNameSpec = NNS; + ForceSpecifierReplacement = (NNS != 0); + } + + void WillReplaceSpecifier(bool ForceReplacement) { + ForceSpecifierReplacement = ForceReplacement; + } + + bool WillReplaceSpecifier() const { + return ForceSpecifierReplacement; } void setQualifierDistance(unsigned ED) { @@ -116,20 +129,31 @@ public: } /// \brief Gets the pointer to the declaration of the typo correction - NamedDecl* getCorrectionDecl() const { + NamedDecl *getCorrectionDecl() const { return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : 0; } template <class DeclClass> DeclClass *getCorrectionDeclAs() const { return dyn_cast_or_null<DeclClass>(getCorrectionDecl()); } - + + /// \brief Clears the list of NamedDecls. + void ClearCorrectionDecls() { + CorrectionDecls.clear(); + } + /// \brief Clears the list of NamedDecls before adding the new one. void setCorrectionDecl(NamedDecl *CDecl) { CorrectionDecls.clear(); addCorrectionDecl(CDecl); } + /// \brief Clears the list of NamedDecls and adds the given set. + void setCorrectionDecls(ArrayRef<NamedDecl*> Decls) { + CorrectionDecls.clear(); + CorrectionDecls.insert(CorrectionDecls.begin(), Decls.begin(), Decls.end()); + } + /// \brief Add the given NamedDecl to the list of NamedDecls that are the /// declarations associated with the DeclarationName of this TypoCorrection void addCorrectionDecl(NamedDecl *CDecl); @@ -140,7 +164,7 @@ public: } /// \brief Returns whether this TypoCorrection has a non-empty DeclarationName - operator bool() const { return bool(CorrectionName); } + LLVM_EXPLICIT operator bool() const { return bool(CorrectionName); } /// \brief Mark this TypoCorrection as being a keyword. /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be @@ -149,6 +173,7 @@ public: void makeKeyword() { CorrectionDecls.clear(); CorrectionDecls.push_back(0); + ForceSpecifierReplacement = true; } // Check if this TypoCorrection is a keyword by checking if the first @@ -171,10 +196,11 @@ public: return CorrectionDecls.size() > 1; } - void setCorrectionRange(CXXScopeSpec* SS, + void setCorrectionRange(CXXScopeSpec *SS, const DeclarationNameInfo &TypoName) { - CorrectionRange.setBegin(CorrectionNameSpec && SS ? SS->getBeginLoc() - : TypoName.getLoc()); + CorrectionRange.setBegin(ForceSpecifierReplacement && SS && !SS->isEmpty() + ? SS->getBeginLoc() + : TypoName.getLoc()); CorrectionRange.setEnd(TypoName.getLoc()); } @@ -182,17 +208,22 @@ public: return CorrectionRange; } - typedef SmallVector<NamedDecl *, 1>::iterator decl_iterator; + typedef SmallVectorImpl<NamedDecl *>::iterator decl_iterator; decl_iterator begin() { return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); } decl_iterator end() { return CorrectionDecls.end(); } - typedef SmallVector<NamedDecl *, 1>::const_iterator const_decl_iterator; + typedef SmallVectorImpl<NamedDecl *>::const_iterator const_decl_iterator; const_decl_iterator begin() const { return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); } const_decl_iterator end() const { return CorrectionDecls.end(); } + /// \brief Returns whether this typo correction is correcting to a + /// declaration that was declared in a module that has not been imported. + bool requiresImport() const { return RequiresImport; } + void setRequiresImport(bool Req) { RequiresImport = Req; } + private: bool hasCorrectionDecl() const { return (!isKeyword() && !CorrectionDecls.empty()); @@ -206,12 +237,14 @@ private: unsigned QualifierDistance; unsigned CallbackDistance; SourceRange CorrectionRange; + bool ForceSpecifierReplacement; + bool RequiresImport; }; /// @brief Base class for callback objects used by Sema::CorrectTypo to check /// the validity of a potential typo correction. class CorrectionCandidateCallback { - public: +public: static const unsigned InvalidDistance = TypoCorrection::InvalidDistance; CorrectionCandidateCallback() @@ -260,12 +293,42 @@ class CorrectionCandidateCallback { /// to ones having a single Decl* of the given type. template <class C> class DeclFilterCCC : public CorrectionCandidateCallback { - public: +public: virtual bool ValidateCandidate(const TypoCorrection &candidate) { return candidate.getCorrectionDeclAs<C>(); } }; +// @brief Callback class to limit the allowed keywords and to only accept typo +// corrections that are keywords or whose decls refer to functions (or template +// functions) that accept the given number of arguments. +class FunctionCallFilterCCC : public CorrectionCandidateCallback { +public: + FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs, + bool HasExplicitTemplateArgs); + + virtual bool ValidateCandidate(const TypoCorrection &candidate); + + private: + unsigned NumArgs; + bool HasExplicitTemplateArgs; +}; + +// @brief Callback class that effectively disabled typo correction +class NoTypoCorrectionCCC : public CorrectionCandidateCallback { +public: + NoTypoCorrectionCCC() { + WantTypeSpecifiers = false; + WantExpressionKeywords = false; + WantCXXNamedCasts = false; + WantRemainingKeywords = false; + } + + virtual bool ValidateCandidate(const TypoCorrection &candidate) { + return false; + } +}; + } #endif diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h index 81f8980..03d9050 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h @@ -535,7 +535,10 @@ namespace clang { /// \brief Record code for undefined but used functions and variables that /// need a definition in this TU. - UNDEFINED_BUT_USED = 49 + UNDEFINED_BUT_USED = 49, + + /// \brief Record code for late parsed template functions. + LATE_PARSED_TEMPLATE = 50 }; /// \brief Record types used within a source manager block. @@ -623,7 +626,9 @@ namespace clang { /// \brief Specifies a configuration macro for this module. SUBMODULE_CONFIG_MACRO = 11, /// \brief Specifies a conflict with another module. - SUBMODULE_CONFLICT = 12 + SUBMODULE_CONFLICT = 12, + /// \brief Specifies a header that is private to this submodule. + SUBMODULE_PRIVATE_HEADER = 13 }; /// \brief Record types used within a comments block. @@ -834,7 +839,9 @@ namespace clang { /// \brief A UnaryTransformType record. TYPE_UNARY_TRANSFORM = 39, /// \brief An AtomicType record. - TYPE_ATOMIC = 40 + TYPE_ATOMIC = 40, + /// \brief A DecayedType record. + TYPE_DECAYED = 41 }; /// \brief The type IDs for special types constructed by semantic @@ -1023,6 +1030,12 @@ namespace clang { DECL_CLASS_TEMPLATE_SPECIALIZATION, /// \brief A ClassTemplatePartialSpecializationDecl record. DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION, + /// \brief A VarTemplateDecl record. + DECL_VAR_TEMPLATE, + /// \brief A VarTemplateSpecializationDecl record. + DECL_VAR_TEMPLATE_SPECIALIZATION, + /// \brief A VarTemplatePartialSpecializationDecl record. + DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION, /// \brief A FunctionTemplateDecl record. DECL_FUNCTION_TEMPLATE, /// \brief A TemplateTypeParmDecl record. @@ -1050,7 +1063,7 @@ namespace clang { DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION, /// \brief An ImportDecl recording a module import. DECL_IMPORT, - /// \brief A OMPThreadPrivateDecl record. + /// \brief An OMPThreadPrivateDecl record. DECL_OMP_THREADPRIVATE, /// \brief An EmptyDecl record. DECL_EMPTY @@ -1173,6 +1186,8 @@ namespace clang { EXPR_GNU_NULL, /// \brief A ShuffleVectorExpr record. EXPR_SHUFFLE_VECTOR, + /// \brief A ConvertVectorExpr record. + EXPR_CONVERT_VECTOR, /// \brief BlockExpr EXPR_BLOCK, /// \brief A GenericSelectionExpr record. @@ -1259,6 +1274,8 @@ namespace clang { EXPR_CXX_FUNCTIONAL_CAST, /// \brief A UserDefinedLiteral record. EXPR_USER_DEFINED_LITERAL, + /// \brief A CXXStdInitializerListExpr record. + EXPR_CXX_STD_INITIALIZER_LIST, /// \brief A CXXBoolLiteralExpr record. EXPR_CXX_BOOL_LITERAL, EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr @@ -1313,7 +1330,10 @@ namespace clang { STMT_SEH_EXCEPT, // SEHExceptStmt STMT_SEH_FINALLY, // SEHFinallyStmt STMT_SEH_TRY, // SEHTryStmt - + + // OpenMP drectives + STMT_OMP_PARALLEL_DIRECTIVE, + // ARC EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h index 2c0102e..d3cca1a 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h @@ -88,7 +88,7 @@ class TypeLocReader; struct HeaderFileInfo; class VersionTuple; class TargetOptions; -class ASTUnresolvedSet; +class LazyASTUnresolvedSet; /// \brief Abstract interface for callback invocations by the ASTReader. /// @@ -166,9 +166,6 @@ public: return false; } - /// \brief Receives a HeaderFileInfo entry. - virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) {} - /// \brief Receives __COUNTER__ value. virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value) {} @@ -190,11 +187,9 @@ class PCHValidator : public ASTReaderListener { Preprocessor &PP; ASTReader &Reader; - unsigned NumHeaderInfos; - public: PCHValidator(Preprocessor &PP, ASTReader &Reader) - : PP(PP), Reader(Reader), NumHeaderInfos(0) {} + : PP(PP), Reader(Reader) {} virtual bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain); @@ -203,7 +198,6 @@ public: virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain, std::string &SuggestedPredefines); - virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID); virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value); private: @@ -246,6 +240,7 @@ class ASTReader { public: typedef SmallVector<uint64_t, 64> RecordData; + typedef SmallVectorImpl<uint64_t> RecordDataImpl; /// \brief The result of reading the control block of an AST file, which /// can fail for various reasons. @@ -315,6 +310,10 @@ private: /// \brief The module manager which manages modules and their dependencies ModuleManager ModuleMgr; + /// \brief The location where the module file will be considered as + /// imported from. For non-module AST types it should be invalid. + SourceLocation CurrentImportLoc; + /// \brief The global module index, if loaded. llvm::OwningPtr<GlobalModuleIndex> GlobalIndex; @@ -712,6 +711,9 @@ private: /// SourceLocation of a matching ODR-use. SmallVector<uint64_t, 8> UndefinedButUsed; + // \brief A list of late parsed template function data. + SmallVector<uint64_t, 1> LateParsedTemplates; + /// \brief A list of modules that were imported by precompiled headers or /// any other non-module AST file. SmallVector<serialization::SubmoduleID, 2> ImportedModules; @@ -873,6 +875,14 @@ private: /// been completed. std::deque<PendingDeclContextInfo> PendingDeclContextInfos; + /// \brief The set of NamedDecls that have been loaded, but are members of a + /// context that has been merged into another context where the corresponding + /// declaration is either missing or has not yet been loaded. + /// + /// We will check whether the corresponding declaration is in fact missing + /// once recursing loading has been completed. + llvm::SmallVector<NamedDecl *, 16> PendingOdrMergeChecks; + /// \brief The set of Objective-C categories that have been deserialized /// since the last time the declaration chains were linked. llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized; @@ -909,16 +919,22 @@ private: /// the given canonical declaration. MergedDeclsMap::iterator combineStoredMergedDecls(Decl *Canon, serialization::GlobalDeclID CanonID); - - /// \brief Ready to load the previous declaration of the given Decl. - void loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID); + + /// \brief A mapping from DeclContexts to the semantic DeclContext that we + /// are treating as the definition of the entity. This is used, for instance, + /// when merging implicit instantiations of class templates across modules. + llvm::DenseMap<DeclContext *, DeclContext *> MergedDeclContexts; + + /// \brief A mapping from canonical declarations of enums to their canonical + /// definitions. Only populated when using modules in C++. + llvm::DenseMap<EnumDecl *, EnumDecl *> EnumDefinitions; /// \brief When reading a Stmt tree, Stmt operands are placed in this stack. SmallVector<Stmt *, 16> StmtStack; /// \brief What kind of records we are reading. enum ReadingKind { - Read_Decl, Read_Type, Read_Stmt + Read_None, Read_Decl, Read_Type, Read_Stmt }; /// \brief What kind of records we are reading. @@ -1238,7 +1254,7 @@ public: void setDeserializationListener(ASTDeserializationListener *Listener); /// \brief Determine whether this AST reader has a global index. - bool hasGlobalIndex() const { return GlobalIndex; } + bool hasGlobalIndex() const { return GlobalIndex.isValid(); } /// \brief Attempts to load the global index. /// @@ -1252,6 +1268,9 @@ public: /// \brief Initializes the ASTContext void InitializeContext(); + /// \brief Update the state of Sema after loading some additional modules. + void UpdateSema(); + /// \brief Add in-memory (virtual file) buffer. void addInMemoryBuffer(StringRef &FileName, llvm::MemoryBuffer *Buffer) { ModuleMgr.addInMemoryBuffer(FileName, Buffer); @@ -1386,6 +1405,10 @@ public: ReadTemplateArgumentLoc(ModuleFile &F, const RecordData &Record, unsigned &Idx); + const ASTTemplateArgumentListInfo* + ReadASTTemplateArgumentListInfo(ModuleFile &F, + const RecordData &Record, unsigned &Index); + /// \brief Reads a declarator info from the given record. TypeSourceInfo *GetTypeSourceInfo(ModuleFile &F, const RecordData &Record, unsigned &Idx); @@ -1612,6 +1635,9 @@ public: SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending); + virtual void ReadLateParsedTemplates( + llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap); + /// \brief Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); @@ -1734,12 +1760,12 @@ public: /// \brief Read a template argument array. void - ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs, + ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, ModuleFile &F, const RecordData &Record, unsigned &Idx); /// \brief Read a UnresolvedSet structure. - void ReadUnresolvedSet(ModuleFile &F, ASTUnresolvedSet &Set, + void ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set, const RecordData &Record, unsigned &Idx); /// \brief Read a C++ base specifier. @@ -1762,7 +1788,8 @@ public: /// \brief Read a source location. SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, - const RecordData &Record, unsigned &Idx) { + const RecordDataImpl &Record, + unsigned &Idx) { return ReadSourceLocation(ModuleFile, Record[Idx++]); } @@ -1813,7 +1840,7 @@ public: Expr *ReadSubExpr(); /// \brief Reads a token out of a record. - Token ReadToken(ModuleFile &M, const RecordData &Record, unsigned &Idx); + Token ReadToken(ModuleFile &M, const RecordDataImpl &Record, unsigned &Idx); /// \brief Reads the macro record located at the given offset. MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset); diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h index 8ac8fde..07fdd06 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h @@ -424,7 +424,8 @@ private: StringRef isysroot, const std::string &OutputFile); void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts, - StringRef isysroot); + StringRef isysroot, + bool Modules); void WriteSourceManagerBlock(SourceManager &SourceMgr, const Preprocessor &PP, StringRef isysroot); @@ -456,7 +457,8 @@ private: void WriteObjCCategories(); void WriteRedeclarations(); void WriteMergedDecls(); - + void WriteLateParsedTemplates(Sema &SemaRef); + unsigned DeclParmVarAbbrev; unsigned DeclContextLexicalAbbrev; unsigned DeclContextVisibleLookupAbbrev; @@ -575,6 +577,11 @@ public: void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, RecordDataImpl &Record); + /// \brief Emits an AST template argument list info. + void AddASTTemplateArgumentListInfo( + const ASTTemplateArgumentListInfo *ASTTemplArgList, + RecordDataImpl &Record); + /// \brief Emit a reference to a declaration. void AddDeclRef(const Decl *D, RecordDataImpl &Record); @@ -723,8 +730,12 @@ public: virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D); virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D); + virtual void + AddedCXXTemplateSpecialization(const VarTemplateDecl *TD, + const VarTemplateSpecializationDecl *D); virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, const FunctionDecl *D); + virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType); virtual void CompletedImplicitDefinition(const FunctionDecl *D); virtual void StaticDataMemberInstantiated(const VarDecl *D); virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, @@ -732,6 +743,7 @@ public: virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, const ObjCPropertyDecl *OrigProp, const ObjCCategoryDecl *ClassExt); + void DeclarationMarkedUsed(const Decl *D) LLVM_OVERRIDE; }; /// \brief AST and semantic-analysis consumer that generates a @@ -746,6 +758,8 @@ class PCHGenerator : public SemaConsumer { SmallVector<char, 128> Buffer; llvm::BitstreamWriter Stream; ASTWriter Writer; + bool AllowASTWithErrors; + bool HasEmittedPCH; protected: ASTWriter &getWriter() { return Writer; } @@ -754,12 +768,15 @@ protected: public: PCHGenerator(const Preprocessor &PP, StringRef OutputFile, clang::Module *Module, - StringRef isysroot, raw_ostream *Out); + StringRef isysroot, raw_ostream *Out, + bool AllowASTWithErrors = false); ~PCHGenerator(); virtual void InitializeSema(Sema &S) { SemaPtr = &S; } virtual void HandleTranslationUnit(ASTContext &Ctx); virtual ASTMutationListener *GetASTMutationListener(); virtual ASTDeserializationListener *GetASTDeserializationListener(); + + bool hasEmittedPCH() const { return HasEmittedPCH; } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/GlobalModuleIndex.h b/contrib/llvm/tools/clang/include/clang/Serialization/GlobalModuleIndex.h index ab91f40..76414ba 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/GlobalModuleIndex.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/GlobalModuleIndex.h @@ -34,6 +34,7 @@ namespace clang { class DirectoryEntry; class FileEntry; class FileManager; +class IdentifierIterator; namespace serialization { class ModuleFile; diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h index b2c4063..ca643ba 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h @@ -96,9 +96,9 @@ class ModuleManager { void returnVisitState(VisitState *State); public: - typedef SmallVector<ModuleFile*, 2>::iterator ModuleIterator; - typedef SmallVector<ModuleFile*, 2>::const_iterator ModuleConstIterator; - typedef SmallVector<ModuleFile*, 2>::reverse_iterator ModuleReverseIterator; + typedef SmallVectorImpl<ModuleFile*>::iterator ModuleIterator; + typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator; + typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator; typedef std::pair<uint32_t, StringRef> ModuleOffset; explicit ModuleManager(FileManager &FileMgr); diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/SerializationDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Serialization/SerializationDiagnostic.h index e63f814..c28cfea 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/SerializationDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/SerializationDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define SERIALIZATIONSTART #include "clang/Basic/DiagnosticSerializationKinds.inc" #undef DIAG diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h new file mode 100644 index 0000000..5978299 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h @@ -0,0 +1,223 @@ +//==-- ObjCRetainCount.h - Retain count summaries for Cocoa -------*- 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 core data structures for retain count "summaries" +// for Objective-C and Core Foundation APIs. These summaries are used +// by the static analyzer to summarize the retain/release effects of +// function and method calls. This drives a path-sensitive typestate +// analysis in the static analyzer, but can also potentially be used by +// other clients. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_OBJCRETAINCOUNT_H +#define LLVM_CLANG_OBJCRETAINCOUNT_H + +namespace clang { namespace ento { namespace objc_retain { + +/// An ArgEffect summarizes the retain count behavior on an argument or receiver +/// to a function or method. +enum ArgEffect { + /// There is no effect. + DoNothing, + + /// The argument is treated as if an -autorelease message had been sent to + /// the referenced object. + Autorelease, + + /// The argument is treated as if an -dealloc message had been sent to + /// the referenced object. + Dealloc, + + /// The argument has its reference count decreased by 1. This is as + /// if CFRelease has been called on the argument. + DecRef, + + /// The argument has its reference count decreased by 1. This is as + /// if a -release message has been sent to the argument. This differs + /// in behavior from DecRef when GC is enabled. + DecRefMsg, + + /// The argument has its reference count decreased by 1 to model + /// a transferred bridge cast under ARC. + DecRefBridgedTransferred, + + /// The argument has its reference count increased by 1. This is as + /// if a -retain message has been sent to the argument. This differs + /// in behavior from IncRef when GC is enabled. + IncRefMsg, + + /// The argument has its reference count increased by 1. This is as + /// if CFRetain has been called on the argument. + IncRef, + + /// The argument acts as if has been passed to CFMakeCollectable, which + /// transfers the object to the Garbage Collector under GC. + MakeCollectable, + + /// The argument is treated as potentially escaping, meaning that + /// even when its reference count hits 0 it should be treated as still + /// possibly being alive as someone else *may* be holding onto the object. + MayEscape, + + /// All typestate tracking of the object ceases. This is usually employed + /// when the effect of the call is completely unknown. + StopTracking, + + /// All typestate tracking of the object ceases. Unlike StopTracking, + /// this is also enforced when the method body is inlined. + /// + /// In some cases, we obtain a better summary for this checker + /// by looking at the call site than by inlining the function. + /// Signifies that we should stop tracking the symbol even if + /// the function is inlined. + StopTrackingHard, + + /// Performs the combined functionality of DecRef and StopTrackingHard. + /// + /// The models the effect that the called function decrements the reference + /// count of the argument and all typestate tracking on that argument + /// should cease. + DecRefAndStopTrackingHard, + + /// Performs the combined functionality of DecRefMsg and StopTrackingHard. + /// + /// The models the effect that the called function decrements the reference + /// count of the argument and all typestate tracking on that argument + /// should cease. + DecRefMsgAndStopTrackingHard +}; + +/// RetEffect summarizes a call's retain/release behavior with respect +/// to its return value. +class RetEffect { +public: + enum Kind { + /// Indicates that no retain count information is tracked for + /// the return value. + NoRet, + /// Indicates that the returned value is an owned (+1) symbol. + OwnedSymbol, + /// Indicates that the returned value is an owned (+1) symbol and + /// that it should be treated as freshly allocated. + OwnedAllocatedSymbol, + /// Indicates that the returned value is an object with retain count + /// semantics but that it is not owned (+0). This is the default + /// for getters, etc. + NotOwnedSymbol, + /// Indicates that the object is not owned and controlled by the + /// Garbage collector. + GCNotOwnedSymbol, + /// Indicates that the object is not owned and controlled by ARC. + ARCNotOwnedSymbol, + /// Indicates that the return value is an owned object when the + /// receiver is also a tracked object. + OwnedWhenTrackedReceiver, + // Treat this function as returning a non-tracked symbol even if + // the function has been inlined. This is used where the call + // site summary is more presise than the summary indirectly produced + // by inlining the function + NoRetHard + }; + + /// Determines the object kind of a tracked object. + enum ObjKind { + /// Indicates that the tracked object is a CF object. This is + /// important between GC and non-GC code. + CF, + /// Indicates that the tracked object is an Objective-C object. + ObjC, + /// Indicates that the tracked object could be a CF or Objective-C object. + AnyObj + }; + +private: + Kind K; + ObjKind O; + + RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {} + +public: + Kind getKind() const { return K; } + + ObjKind getObjKind() const { return O; } + + bool isOwned() const { + return K == OwnedSymbol || K == OwnedAllocatedSymbol || + K == OwnedWhenTrackedReceiver; + } + + bool notOwned() const { + return K == NotOwnedSymbol || K == ARCNotOwnedSymbol; + } + + bool operator==(const RetEffect &Other) const { + return K == Other.K && O == Other.O; + } + + static RetEffect MakeOwnedWhenTrackedReceiver() { + return RetEffect(OwnedWhenTrackedReceiver, ObjC); + } + + static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) { + return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o); + } + static RetEffect MakeNotOwned(ObjKind o) { + return RetEffect(NotOwnedSymbol, o); + } + static RetEffect MakeGCNotOwned() { + return RetEffect(GCNotOwnedSymbol, ObjC); + } + static RetEffect MakeARCNotOwned() { + return RetEffect(ARCNotOwnedSymbol, ObjC); + } + static RetEffect MakeNoRet() { + return RetEffect(NoRet); + } + static RetEffect MakeNoRetHard() { + return RetEffect(NoRetHard); + } +}; + +/// Encapsulates the retain count semantics on the arguments, return value, +/// and receiver (if any) of a function/method call. +/// +/// Note that construction of these objects is not highly efficient. That +/// is okay for clients where creating these objects isn't really a bottleneck. +/// The purpose of the API is to provide something simple. The actual +/// static analyzer checker that implements retain/release typestate +/// tracking uses something more efficient. +class CallEffects { + llvm::SmallVector<ArgEffect, 10> Args; + RetEffect Ret; + ArgEffect Receiver; + + CallEffects(const RetEffect &R) : Ret(R) {} + +public: + /// Returns the argument effects for a call. + llvm::ArrayRef<ArgEffect> getArgs() const { return Args; } + + /// Returns the effects on the receiver. + ArgEffect getReceiver() const { return Receiver; } + + /// Returns the effect on the return value. + RetEffect getReturnValue() const { return Ret; } + + /// Return the CallEfect for a given Objective-C method. + static CallEffects getEffect(const ObjCMethodDecl *MD); + + /// Return the CallEfect for a given C/C++ function. + static CallEffects getEffect(const FunctionDecl *FD); +}; + +}}} + +#endif + diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Analyses.def b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Analyses.def index dc79450..3355f4b 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Analyses.def +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Analyses.def @@ -24,14 +24,14 @@ ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateR ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager) #ifndef ANALYSIS_DIAGNOSTICS -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) #endif -ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer, false) -ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer, true) -ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer, true) -ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer, true) -ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer, true) +ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer) +ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer) +ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer) +ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer) +ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer) #ifndef ANALYSIS_PURGE #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index fb35f51..618782e 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -52,7 +52,7 @@ NumConstraints /// AnalysisDiagClients - Set of available diagnostic clients for rendering /// analysis results. enum AnalysisDiagClients { -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) PD_##NAME, +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME, #include "clang/StaticAnalyzer/Core/Analyses.def" NUM_ANALYSIS_DIAG_CLIENTS }; @@ -201,6 +201,9 @@ private: /// \sa mayInlineCXXContainerCtorsAndDtors Optional<bool> InlineCXXContainerCtorsAndDtors; + /// \sa mayInlineCXXSharedPtrDtor + Optional<bool> InlineCXXSharedPtrDtor; + /// \sa mayInlineObjCMethod Optional<bool> ObjCInliningMode; @@ -223,6 +226,9 @@ private: /// \sa shouldSuppressFromCXXStandardLibrary Optional<bool> SuppressFromCXXStandardLibrary; + /// \sa reportIssuesInMainSourceFile + Optional<bool> ReportIssuesInMainSourceFile; + /// \sa getGraphTrimInterval Optional<unsigned> GraphTrimInterval; @@ -291,6 +297,16 @@ public: /// accepts the values "true" and "false". bool mayInlineCXXContainerCtorsAndDtors(); + /// Returns whether or not the destructor of C++ 'shared_ptr' may be + /// considered for inlining. + /// + /// This covers std::shared_ptr, std::tr1::shared_ptr, and boost::shared_ptr, + /// and indeed any destructor named "~shared_ptr". + /// + /// This is controlled by the 'c++-shared_ptr-inlining' config option, which + /// accepts the values "true" and "false". + bool mayInlineCXXSharedPtrDtor(); + /// Returns whether or not paths that go through null returns should be /// suppressed. /// @@ -326,6 +342,13 @@ public: /// which accepts the values "true" and "false". bool shouldSuppressFromCXXStandardLibrary(); + /// Returns whether or not the diagnostic report should be always reported + /// in the main source file and not the headers. + /// + /// This is controlled by the 'report-in-main-source-file' config option, + /// which accepts the values "true" and "false". + bool shouldReportIssuesInMainSourceFile(); + /// Returns whether irrelevant parts of a bug report path should be pruned /// out of the final output. /// 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 5c560b2..9584b8b 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 @@ -16,6 +16,7 @@ #define LLVM_CLANG_GR_BUGREPORTER #include "clang/Basic/SourceLocation.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" @@ -375,6 +376,7 @@ public: virtual ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() = 0; virtual ASTContext &getASTContext() = 0; virtual SourceManager& getSourceManager() = 0; + virtual AnalyzerOptions& getAnalyzerOptions() = 0; }; /// BugReporter is a utility class for generating PathDiagnostics for analysis. @@ -442,6 +444,8 @@ public: SourceManager& getSourceManager() { return D.getSourceManager(); } + AnalyzerOptions& getAnalyzerOptions() { return D.getAnalyzerOptions(); } + virtual bool generatePathDiagnostic(PathDiagnostic& pathDiagnostic, PathDiagnosticConsumer &PC, ArrayRef<BugReport *> &bugReports) { @@ -462,20 +466,7 @@ public: void EmitBasicReport(const Decl *DeclWithIssue, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, - SourceRange* RangeBeg, unsigned NumRanges); - - void EmitBasicReport(const Decl *DeclWithIssue, - StringRef BugName, StringRef BugCategory, - StringRef BugStr, PathDiagnosticLocation Loc) { - EmitBasicReport(DeclWithIssue, BugName, BugCategory, BugStr, Loc, 0, 0); - } - - void EmitBasicReport(const Decl *DeclWithIssue, - StringRef BugName, StringRef Category, - StringRef BugStr, PathDiagnosticLocation Loc, - SourceRange R) { - EmitBasicReport(DeclWithIssue, BugName, Category, BugStr, Loc, &R, 1); - } + ArrayRef<SourceRange> Ranges = None); private: llvm::StringMap<BugType *> StrBugTypes; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h index 644aa31..49f9c83 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_ANALYSIS_BUGTYPE #define LLVM_CLANG_ANALYSIS_BUGTYPE +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/FoldingSet.h" #include <string> @@ -31,10 +32,12 @@ private: const std::string Name; const std::string Category; bool SuppressonSink; + + virtual void anchor(); public: BugType(StringRef name, StringRef cat) : Name(name), Category(cat), SuppressonSink(false) {} - virtual ~BugType(); + virtual ~BugType() {} // FIXME: Should these be made strings as well? StringRef getName() const { return Name; } @@ -50,14 +53,14 @@ public: }; class BuiltinBug : public BugType { - virtual void anchor(); const std::string desc; + virtual void anchor(); public: BuiltinBug(const char *name, const char *description) - : BugType(name, "Logic error"), desc(description) {} + : BugType(name, categories::LogicError), desc(description) {} BuiltinBug(const char *name) - : BugType(name, "Logic error"), desc(name) {} + : BugType(name, categories::LogicError), desc(name) {} StringRef getDescription() const { return desc; } }; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/CommonBugCategories.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h index 9d4251b..3f0fe96 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Checkers/CommonBugCategories.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h @@ -7,16 +7,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_STATIC_ANALYZER_CHECKER_CATEGORIES_H -#define LLVM_CLANG_STATIC_ANALYZER_CHECKER_CATEGORIES_H +#ifndef LLVM_CLANG_STATIC_ANALYZER_BUG_CATEGORIES_H +#define LLVM_CLANG_STATIC_ANALYZER_BUG_CATEGORIES_H // Common strings used for the "category" of many static analyzer issues. namespace clang { namespace ento { namespace categories { - extern const char *CoreFoundationObjectiveC; - extern const char *MemoryCoreFoundationObjectiveC; - extern const char *UnixAPI; + extern const char * const CoreFoundationObjectiveC; + extern const char * const LogicError; + extern const char * const MemoryCoreFoundationObjectiveC; + extern const char * const UnixAPI; } } } 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 a80b5a7..b0670da 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 @@ -38,6 +38,7 @@ class ParentMap; class ProgramPoint; class SourceManager; class Stmt; +class CallExpr; namespace ento { @@ -97,7 +98,6 @@ public: enum PathGenerationScheme { None, Minimal, Extensive, AlternateExtensive }; virtual PathGenerationScheme getGenerationScheme() const { return Minimal; } virtual bool supportsLogicalOpControlFlow() const { return false; } - virtual bool supportsAllBlockEdges() const { return false; } /// Return true if the PathDiagnosticConsumer supports individual /// PathDiagnostics that span multiple files. @@ -285,11 +285,13 @@ public: void Profile(llvm::FoldingSetNodeID &ID) const; + void dump() const; + /// \brief Given an exploded node, retrieve the statement that should be used /// for the diagnostic location. static const Stmt *getStmt(const ExplodedNode *N); - /// \brief Retrieve the statement corresponding to the sucessor node. + /// \brief Retrieve the statement corresponding to the successor node. static const Stmt *getNextStmt(const ExplodedNode *N); }; @@ -331,6 +333,10 @@ private: const std::string str; const Kind kind; const DisplayHint Hint; + + /// \brief In the containing bug report, this piece is the last piece from + /// the main source file. + bool LastInMainSourceFile; /// A constant string that can be used to tag the PathDiagnosticPiece, /// typically with the identification of the creator. The actual pointer @@ -389,6 +395,16 @@ public: ArrayRef<SourceRange> getRanges() const { return ranges; } virtual void Profile(llvm::FoldingSetNodeID &ID) const; + + void setAsLastInMainSourceFile() { + LastInMainSourceFile = true; + } + + bool isLastInMainSourceFile() const { + return LastInMainSourceFile; + } + + virtual void dump() const = 0; }; @@ -403,6 +419,8 @@ public: flattenTo(Result, Result, ShouldFlattenMacros); return Result; } + + LLVM_ATTRIBUTE_USED void dump() const; }; class PathDiagnosticSpotPiece : public PathDiagnosticPiece { @@ -421,7 +439,7 @@ public: PathDiagnosticLocation getLocation() const { return Pos; } virtual void flattenLocations() { Pos.flatten(); } - + virtual void Profile(llvm::FoldingSetNodeID &ID) const; static bool classof(const PathDiagnosticPiece *P) { @@ -504,7 +522,7 @@ public: } bool hasCallStackHint() { - return (CallStackHint != 0); + return CallStackHint.isValid(); } /// Produce the hint for the given node. The node contains @@ -515,6 +533,8 @@ public: return ""; } + virtual void dump() const; + static inline bool classof(const PathDiagnosticPiece *P) { return P->getKind() == Event; } @@ -582,6 +602,8 @@ public: static PathDiagnosticCallPiece *construct(PathPieces &pieces, const Decl *caller); + virtual void dump() const; + virtual void Profile(llvm::FoldingSetNodeID &ID) const; static inline bool classof(const PathDiagnosticPiece *P) { @@ -649,7 +671,9 @@ public: static inline bool classof(const PathDiagnosticPiece *P) { return P->getKind() == ControlFlow; } - + + virtual void dump() const; + virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; @@ -673,7 +697,9 @@ public: static inline bool classof(const PathDiagnosticPiece *P) { return P->getKind() == Macro; } - + + virtual void dump() const; + virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; @@ -687,7 +713,10 @@ class PathDiagnostic : public llvm::FoldingSetNode { std::string ShortDesc; std::string Category; std::deque<std::string> OtherDesc; + + /// \brief Loc The location of the path diagnostic report. PathDiagnosticLocation Loc; + PathPieces pathImpl; SmallVector<PathPieces *, 3> pathStack; @@ -735,12 +764,23 @@ public: getActivePath().push_back(EndPiece); } + void appendToDesc(StringRef S) { + if (!ShortDesc.empty()) + ShortDesc.append(S); + VerboseDesc.append(S); + } + void resetPath() { pathStack.clear(); pathImpl.clear(); Loc = PathDiagnosticLocation(); } - + + /// \brief If the last piece of the report point to the header file, resets + /// the location of the report to be the last location in the main source + /// file. + void resetDiagnosticLocationToMainFile(); + StringRef getVerboseDescription() const { return VerboseDesc; } StringRef getShortDescription() const { return ShortDesc.empty() ? VerboseDesc : ShortDesc; @@ -759,7 +799,7 @@ public: void addMeta(StringRef s) { OtherDesc.push_back(s); } PathDiagnosticLocation getLocation() const { - assert(Loc.isValid() && "No end-of-path location set yet!"); + assert(Loc.isValid() && "No report location set yet!"); return Loc; } 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 0dbaab0..cf7cf05 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -320,18 +320,35 @@ public: class PointerEscape { template <typename CHECKER> static ProgramStateRef - _checkPointerEscape(void *checker, + _checkPointerEscape(void *Checker, ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, - bool IsConst) { - if (!IsConst) - return ((const CHECKER *)checker)->checkPointerEscape(State, + RegionAndSymbolInvalidationTraits *ETraits) { + + if (!ETraits) + return ((const CHECKER *)Checker)->checkPointerEscape(State, Escaped, Call, Kind); - return State; + + InvalidatedSymbols RegularEscape; + for (InvalidatedSymbols::const_iterator I = Escaped.begin(), + E = Escaped.end(); I != E; ++I) + if (!ETraits->hasTrait(*I, + RegionAndSymbolInvalidationTraits::TK_PreserveContents) && + !ETraits->hasTrait(*I, + RegionAndSymbolInvalidationTraits::TK_SuppressEscape)) + RegularEscape.insert(*I); + + if (RegularEscape.empty()) + return State; + + return ((const CHECKER *)Checker)->checkPointerEscape(State, + RegularEscape, + Call, + Kind); } public: @@ -346,18 +363,32 @@ public: class ConstPointerEscape { template <typename CHECKER> static ProgramStateRef - _checkConstPointerEscape(void *checker, + _checkConstPointerEscape(void *Checker, ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, - bool IsConst) { - if (IsConst) - return ((const CHECKER *)checker)->checkConstPointerEscape(State, - Escaped, - Call, - Kind); - return State; + RegionAndSymbolInvalidationTraits *ETraits) { + + if (!ETraits) + return State; + + InvalidatedSymbols ConstEscape; + for (InvalidatedSymbols::const_iterator I = Escaped.begin(), + E = Escaped.end(); I != E; ++I) + if (ETraits->hasTrait(*I, + RegionAndSymbolInvalidationTraits::TK_PreserveContents) && + !ETraits->hasTrait(*I, + RegionAndSymbolInvalidationTraits::TK_SuppressEscape)) + ConstEscape.insert(*I); + + if (ConstEscape.empty()) + return State; + + return ((const CHECKER *)Checker)->checkConstPointerEscape(State, + ConstEscape, + Call, + Kind); } public: @@ -502,10 +533,14 @@ struct ImplicitNullDerefEvent { }; /// \brief A helper class which wraps a boolean value set to false by default. +/// +/// This class should behave exactly like 'bool' except that it doesn't need to +/// be explicitly initialized. struct DefaultBool { bool val; DefaultBool() : val(false) {} - operator bool() const { return val; } + /*implicit*/ operator bool&() { return val; } + /*implicit*/ operator const bool&() const { return val; } DefaultBool &operator=(bool b) { val = b; return *this; } }; 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 b2411e6..8ad67c1 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -19,7 +19,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" #include <vector> @@ -366,14 +365,16 @@ public: /// \param Escaped The list of escaped symbols. /// \param Call The corresponding CallEvent, if the symbols escape as /// parameters to the given call. - /// \param IsConst Specifies if the pointer is const. + /// \param Kind The reason of pointer escape. + /// \param ITraits Information about invalidation for a particular + /// region/symbol. /// \returns Checkers can modify the state by returning a new one. ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, - bool IsConst = false); + RegionAndSymbolInvalidationTraits *ITraits); /// \brief Run checkers for handling assumptions on symbolic values. ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, @@ -465,7 +466,7 @@ public: const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, - bool IsConst)> + RegionAndSymbolInvalidationTraits *ITraits)> CheckPointerEscapeFunc; typedef CheckerFn<ProgramStateRef (ProgramStateRef, @@ -581,35 +582,12 @@ private: }; std::vector<StmtCheckerInfo> StmtCheckers; - struct CachedStmtCheckersKey { - unsigned StmtKind; - bool IsPreVisit; - - CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { } - CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit) - : StmtKind(stmtKind), IsPreVisit(isPreVisit) { } - - static CachedStmtCheckersKey getSentinel() { - return CachedStmtCheckersKey(~0U, 0); - } - unsigned getHashValue() const { - llvm::FoldingSetNodeID ID; - ID.AddInteger(StmtKind); - ID.AddBoolean(IsPreVisit); - return ID.ComputeHash(); - } - bool operator==(const CachedStmtCheckersKey &RHS) const { - return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit; - } - }; - friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>; - typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; - typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers> - CachedStmtCheckersMapTy; + typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy; CachedStmtCheckersMapTy CachedStmtCheckersMap; - CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit); + const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S, + bool isPreVisit); std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; @@ -659,30 +637,4 @@ private: } // end clang namespace -namespace llvm { - /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key - /// in DenseMap and DenseSets. - template <> - struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> { - static inline clang::ento::CheckerManager::CachedStmtCheckersKey - getEmptyKey() { - return clang::ento::CheckerManager::CachedStmtCheckersKey(); - } - static inline clang::ento::CheckerManager::CachedStmtCheckersKey - getTombstoneKey() { - return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel(); - } - - static unsigned - getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) { - return S.getHashValue(); - } - - static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS, - clang::ento::CheckerManager::CachedStmtCheckersKey RHS) { - return LHS == RHS; - } - }; -} // end namespace llvm - #endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h index 4557aa4..ca68a74 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h @@ -54,10 +54,6 @@ // // For a complete working example, see examples/analyzer-plugin. - -namespace clang { -namespace ento { - #ifndef CLANG_ANALYZER_API_VERSION_STRING // FIXME: The Clang version string is not particularly granular; // the analyzer infrastructure can change a lot between releases. @@ -67,6 +63,9 @@ namespace ento { #define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING #endif +namespace clang { +namespace ento { + class CheckerOptInfo; /// Manages a set of available checkers for running a static analysis. diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h index b856de7..43e9166 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h @@ -27,18 +27,12 @@ namespace ento { class PathDiagnosticConsumer; typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers; -#define CREATE_CONSUMER(NAME)\ -void create ## NAME ## DiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,\ - PathDiagnosticConsumers &C,\ - const std::string& prefix,\ - const Preprocessor &PP); - -CREATE_CONSUMER(HTML) -CREATE_CONSUMER(Plist) -CREATE_CONSUMER(PlistMultiFile) -CREATE_CONSUMER(TextPath) - -#undef CREATE_CONSUMER +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)\ +void CREATEFN(AnalyzerOptions &AnalyzerOpts,\ + PathDiagnosticConsumers &C,\ + const std::string &Prefix,\ + const Preprocessor &PP); +#include "clang/StaticAnalyzer/Core/Analyses.def" } // end 'ento' namespace } // end 'clang' namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index 458c896..d7d83ce 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 @@ -65,6 +65,10 @@ public: StoreManagerCreator getStoreManagerCreator() { return CreateStoreMgr; } + + AnalyzerOptions& getAnalyzerOptions() { + return options; + } ConstraintManagerCreator getConstraintManagerCreator() { return CreateConstraintMgr; 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 f990b8d..cfaf085 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 @@ -228,11 +228,6 @@ public: return false; } - /// \brief Returns true if this is a call to a variadic function or method. - virtual bool isVariadic() const { - return false; - } - /// \brief Returns a source range for the entire call, suitable for /// outputting in diagnostics. virtual SourceRange getSourceRange() const { @@ -341,6 +336,11 @@ public: /// This will return a null QualType if the result type cannot be determined. static QualType getDeclaredResultType(const Decl *D); + /// \brief Returns true if the given decl is known to be variadic. + /// + /// \p D must not be null. + static bool isVariadic(const Decl *D); + // Iterator access to formal parameters and their types. private: typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun; @@ -350,19 +350,13 @@ public: /// Returns an iterator over the call's formal parameters. /// - /// If UseDefinitionParams is set, this will return the parameter decls - /// used in the callee's definition (suitable for inlining). Most of the - /// time it is better to use the decl found by name lookup, which likely - /// carries more annotations. - /// /// Remember that the number of formal parameters may not match the number /// of arguments for all calls. However, the first parameter will always /// correspond with the argument value returned by \c getArgSVal(0). /// - /// If the call has no accessible declaration (or definition, if - /// \p UseDefinitionParams is set), \c param_begin() will be equal to - /// \c param_end(). - virtual param_iterator param_begin() const =0; + /// If the call has no accessible declaration, \c param_begin() will be equal + /// to \c param_end(). + virtual param_iterator param_begin() const = 0; /// \sa param_begin() virtual param_iterator param_end() const = 0; @@ -423,10 +417,6 @@ public: return RuntimeDefinition(); } - virtual bool isVariadic() const { - return getDecl()->isVariadic(); - } - virtual bool argumentsMayEscape() const; virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, @@ -527,10 +517,6 @@ public: return RuntimeDefinition(getBlockDecl()); } - virtual bool isVariadic() const { - return getBlockDecl()->isVariadic(); - } - virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const; @@ -849,9 +835,6 @@ public: virtual const Expr *getArgExpr(unsigned Index) const { return getOriginExpr()->getArg(Index); } - virtual bool isVariadic() const { - return getDecl()->isVariadic(); - } bool isInstanceMessage() const { return getOriginExpr()->isInstanceMessage(); 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 edcfc8a..bf17cd8 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 @@ -184,7 +184,7 @@ public: bool isSink() const { return Succs.getFlag(); } - bool hasSinglePred() const { + bool hasSinglePred() const { return (pred_size() == 1); } 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 33e4431..d89dffe 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 @@ -203,6 +203,8 @@ public: void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst); + void ProcessDeleteDtor(const CFGDeleteDtor D, + ExplodedNode *Pred, ExplodedNodeSet &Dst); void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst); void ProcessMemberDtor(const CFGMemberDtor D, @@ -476,14 +478,14 @@ protected: SVal Loc, SVal Val); /// Call PointerEscape callback when a value escapes as a result of /// region invalidation. - /// \param[in] IsConst Specifies that the pointer is const. + /// \param[in] ITraits Specifies invalidation traits for regions/symbols. ProgramStateRef notifyCheckersOfPointerEscape( ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef<const MemRegion *> ExplicitRegions, ArrayRef<const MemRegion *> Regions, const CallEvent *Call, - bool IsConst); + RegionAndSymbolInvalidationTraits &ITraits); public: // FIXME: 'tag' should be removed, and a LocationContext should be used 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 9b4f77d..cc790c1 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 @@ -635,12 +635,14 @@ class BlockDataRegion : public TypedRegion { friend class MemRegionManager; const BlockTextRegion *BC; const LocationContext *LC; // Can be null */ + unsigned BlockCount; void *ReferencedVars; void *OriginalVars; BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, - const MemRegion *sreg) + unsigned count, const MemRegion *sreg) : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), + BlockCount(count), ReferencedVars(0), OriginalVars(0) {} public: @@ -692,7 +694,8 @@ public: void Profile(llvm::FoldingSetNodeID& ID) const; static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *, - const LocationContext *, const MemRegion *); + const LocationContext *, unsigned, + const MemRegion *); static bool classof(const MemRegion* R) { return R->getKind() == BlockDataRegionKind; @@ -1270,7 +1273,13 @@ public: /// argument is allowed to be NULL for cases where we have no known /// context. const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc, - const LocationContext *lc = NULL); + const LocationContext *lc, + unsigned blockCount); + + /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended + /// by static references. This differs from getCXXTempObjectRegion in the + /// super-region used. + const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex); private: template <typename RegionTy, typename A1> @@ -1304,6 +1313,39 @@ private: inline ASTContext &MemRegion::getContext() const { return getMemRegionManager()->getContext(); } + +//===----------------------------------------------------------------------===// +// Means for storing region/symbol handling traits. +//===----------------------------------------------------------------------===// + +/// Information about invalidation for a particular region/symbol. +class RegionAndSymbolInvalidationTraits { + typedef unsigned char StorageTypeForKinds; + llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap; + llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap; + + typedef llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator + const_region_iterator; + typedef llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator + const_symbol_iterator; + +public: + /// \brief Describes different invalidation traits. + enum InvalidationKinds { + /// Tells that a region's contents is not changed. + TK_PreserveContents = 0x1, + /// Suppress pointer-escaping of a region. + TK_SuppressEscape = 0x2 + + // Do not forget to extend StorageTypeForKinds if number of traits exceed + // the number of bits StorageTypeForKinds can store. + }; + + void setTrait(SymbolRef Sym, InvalidationKinds IK); + void setTrait(const MemRegion *MR, InvalidationKinds IK); + bool hasTrait(SymbolRef Sym, InvalidationKinds IK); + bool hasTrait(const MemRegion *MR, InvalidationKinds IK); +}; } // end GR namespace 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 42ef1db..03739ed 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 @@ -232,22 +232,21 @@ public: /// \param IS the set of invalidated symbols. /// \param Call if non-null, the invalidated regions represent parameters to /// the call and should be considered directly invalidated. - /// \param ConstRegions the set of regions whose contents are accessible, - /// even though the regions themselves should not be invalidated. + /// \param ITraits information about special handling for a particular + /// region/symbol. ProgramStateRef invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E, unsigned BlockCount, const LocationContext *LCtx, bool CausesPointerEscape, InvalidatedSymbols *IS = 0, const CallEvent *Call = 0, - ArrayRef<const MemRegion *> ConstRegions = - ArrayRef<const MemRegion *>()) const; + RegionAndSymbolInvalidationTraits *ITraits = 0) const; ProgramStateRef invalidateRegions(ArrayRef<SVal> Regions, const Expr *E, unsigned BlockCount, const LocationContext *LCtx, bool CausesPointerEscape, InvalidatedSymbols *IS = 0, const CallEvent *Call = 0, - ArrayRef<SVal> ConstRegions = ArrayRef<SVal>()) const; + RegionAndSymbolInvalidationTraits *ITraits = 0) const; /// enterStackFrame - Returns the state for entry to the given stack frame, /// preserving the current state. @@ -425,9 +424,9 @@ private: const Expr *E, unsigned BlockCount, const LocationContext *LCtx, bool ResultsInSymbolEscape, - InvalidatedSymbols &IS, - const CallEvent *Call, - ArrayRef<SVal> ConstValues) const; + InvalidatedSymbols *IS, + RegionAndSymbolInvalidationTraits *HTraits, + const CallEvent *Call) const; }; //===----------------------------------------------------------------------===// @@ -516,8 +515,8 @@ public: public: - SVal ArrayToPointer(Loc Array) { - return StoreMgr->ArrayToPointer(Array); + SVal ArrayToPointer(Loc Array, QualType ElementTy) { + return StoreMgr->ArrayToPointer(Array, ElementTy); } // Methods that manipulate the GDM. @@ -798,7 +797,7 @@ CB ProgramState::scanReachableSymbols(const MemRegion * const *beg, /// A Utility class that allows to visit the reachable symbols using a custom /// SymbolVisitor. class ScanReachableSymbols { - typedef llvm::DenseMap<const void*, unsigned> VisitedItems; + typedef llvm::DenseSet<const void*> VisitedItems; VisitedItems visited; ProgramStateRef state; @@ -808,6 +807,7 @@ public: ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v) : state(st), visitor(v) {} + bool scan(nonloc::LazyCompoundVal val); bool scan(nonloc::CompoundVal val); bool scan(SVal val); bool scan(const MemRegion *R); 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 bbb5688..c5d0a92 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 @@ -200,7 +200,8 @@ public: DefinedSVal getFunctionPointer(const FunctionDecl *func); DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, - const LocationContext *locContext); + const LocationContext *locContext, + unsigned blockCount); /// Returns the value of \p E, if it can be determined in a non-path-sensitive /// manner. 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 326e784..5a426ef 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 @@ -290,7 +290,7 @@ public: static inline bool isLocType(QualType T) { return T->isAnyPointerType() || T->isBlockPointerType() || - T->isReferenceType(); + T->isReferenceType() || T->isNullPtrType(); } private: 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 b219495..530dae5 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 @@ -111,7 +111,7 @@ public: /// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit /// conversions between arrays and pointers. - virtual SVal ArrayToPointer(Loc Array) = 0; + virtual SVal ArrayToPointer(Loc Array, QualType ElementTy) = 0; /// Evaluates a chain of derived-to-base casts through the path specified in /// \p Cast. @@ -164,8 +164,6 @@ public: /// the given regions. Optionally, invalidates non-static globals as well. /// \param[in] store The initial store /// \param[in] Values The values to invalidate. - /// \param[in] ConstValues The values to invalidate; these are known to be - /// const, so only regions accesible from them should be invalidated. /// \param[in] E The current statement being evaluated. Used to conjure /// symbols to mark the values of invalidated regions. /// \param[in] Count The current block count. Used to conjure @@ -174,13 +172,10 @@ public: /// globals should get invalidated. /// \param[in,out] IS A set to fill with any symbols that are no longer /// accessible. Pass \c NULL if this information will not be used. - /// \param[in,out] ConstIS A set to fill with any symbols corresponding to - /// the ConstValues. + /// \param[in] ITraits Information about invalidation for a particular + /// region/symbol. /// \param[in,out] InvalidatedTopLevel A vector to fill with regions - //// explicitely being invalidated. Pass \c NULL if this - /// information will not be used. - /// \param[in,out] InvalidatedTopLevelConst A vector to fill with const - //// regions explicitely being invalidated. Pass \c NULL if this + //// explicitly being invalidated. Pass \c NULL if this /// information will not be used. /// \param[in,out] Invalidated A vector to fill with any regions being /// invalidated. This should include any regions explicitly invalidated @@ -188,14 +183,12 @@ public: /// information will not be used. virtual StoreRef invalidateRegions(Store store, ArrayRef<SVal> Values, - ArrayRef<SVal> ConstValues, const Expr *E, unsigned Count, const LocationContext *LCtx, const CallEvent *Call, InvalidatedSymbols &IS, - InvalidatedSymbols &ConstIS, + RegionAndSymbolInvalidationTraits &ITraits, InvalidatedRegions *InvalidatedTopLevel, - InvalidatedRegions *InvalidatedTopLevelConst, InvalidatedRegions *Invalidated) = 0; /// enterStackFrame - Let the StoreManager to do something when execution @@ -231,7 +224,7 @@ public: bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R, SVal val); - operator bool() { return First && Binding; } + LLVM_EXPLICIT operator bool() { return First && Binding; } const MemRegion *getRegion() { return Binding; } }; 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 d410063..f653c70 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 @@ -134,7 +134,7 @@ public: ArrayRef<const MemRegion *> ExplicitRegions, ArrayRef<const MemRegion *> Regions, const CallEvent *Call, - bool IsConst = false) = 0; + RegionAndSymbolInvalidationTraits &HTraits) = 0; /// printState - Called by ProgramStateManager to print checker-specific data. virtual void printState(raw_ostream &Out, ProgramStateRef State, diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/ArgumentsAdjusters.h b/contrib/llvm/tools/clang/include/clang/Tooling/ArgumentsAdjusters.h index 492ddd2..71acef8 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/ArgumentsAdjusters.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/ArgumentsAdjusters.h @@ -52,6 +52,12 @@ class ClangSyntaxOnlyAdjuster : public ArgumentsAdjuster { virtual CommandLineArguments Adjust(const CommandLineArguments &Args); }; +/// \brief An argument adjuster which removes output-related command line +/// arguments. +class ClangStripOutputAdjuster : public ArgumentsAdjuster { + virtual CommandLineArguments Adjust(const CommandLineArguments &Args); +}; + } // end namespace tooling } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h b/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h index 6775934..eaffe43 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h @@ -64,7 +64,7 @@ public: /// 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); + CommonOptionsParser(int &argc, const char **argv, const char *Overview = 0); /// Returns a reference to the loaded compilations database. CompilationDatabase &getCompilations() { diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h index 7a8054f..8cca329 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h @@ -50,6 +50,16 @@ struct CompileCommand { /// \brief The command line that was executed. std::vector<std::string> CommandLine; + + /// \brief An optional mapping from each file's path to its content for all + /// files needed for the compilation that are not available via the file + /// system. + /// + /// Note that a tool implementation is required to fall back to the file + /// system if a source file is not provided in the mapped sources, as + /// compilation databases will usually not provide all files in mapped sources + /// for performance reasons. + std::vector<std::pair<std::string, std::string> > MappedSources; }; /// \brief Interface for compilation databases. @@ -108,6 +118,10 @@ public: /// \brief Returns all compile commands for all the files in the compilation /// database. + /// + /// FIXME: Add a layer in Tooling that provides an interface to run a tool + /// over all files in a compilation database. Not all build systems have the + /// ability to provide a feasible implementation for \c getAllCompileCommands. virtual std::vector<CompileCommand> getAllCompileCommands() const = 0; }; diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/Refactoring.h b/contrib/llvm/tools/clang/include/clang/Tooling/Refactoring.h index 079ce74..43ec9ac 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/Refactoring.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/Refactoring.h @@ -32,6 +32,37 @@ class SourceLocation; namespace tooling { +/// \brief A source range independent of the \c SourceManager. +class Range { +public: + Range() : Offset(0), Length(0) {} + Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {} + + /// \brief Accessors. + /// @{ + unsigned getOffset() const { return Offset; } + unsigned getLength() const { return Length; } + /// @} + + /// \name Range Predicates + /// @{ + /// \brief Whether this range overlaps with \p RHS or not. + bool overlapsWith(Range RHS) const { + return Offset + Length > RHS.Offset && Offset < RHS.Offset + RHS.Length; + } + + /// \brief Whether this range contains \p RHS or not. + bool contains(Range RHS) const { + return RHS.Offset >= Offset && + (RHS.Offset + RHS.Length) <= (Offset + Length); + } + /// @} + +private: + unsigned Offset; + unsigned Length; +}; + /// \brief A text replacement. /// /// Represents a SourceManager independent replacement of a range of text in a @@ -72,8 +103,8 @@ public: /// \brief Accessors. /// @{ StringRef getFilePath() const { return FilePath; } - unsigned getOffset() const { return Offset; } - unsigned getLength() const { return Length; } + unsigned getOffset() const { return ReplacementRange.getOffset(); } + unsigned getLength() const { return ReplacementRange.getLength(); } StringRef getReplacementText() const { return ReplacementText; } /// @} @@ -83,12 +114,6 @@ public: /// \brief Returns a human readable string representation. std::string toString() const; - /// \brief Comparator to be able to use Replacement in std::set for uniquing. - class Less { - public: - bool operator()(const Replacement &R1, const Replacement &R2) const; - }; - private: void setFromSourceLocation(SourceManager &Sources, SourceLocation Start, unsigned Length, StringRef ReplacementText); @@ -96,14 +121,27 @@ public: StringRef ReplacementText); std::string FilePath; - unsigned Offset; - unsigned Length; + Range ReplacementRange; std::string ReplacementText; }; +/// \brief Less-than operator between two Replacements. +bool operator<(const Replacement &LHS, const Replacement &RHS); + +/// \brief Equal-to operator between two Replacements. +bool operator==(const Replacement &LHS, const Replacement &RHS); + /// \brief A set of Replacements. /// FIXME: Change to a vector and deduplicate in the RefactoringTool. -typedef std::set<Replacement, Replacement::Less> Replacements; +typedef std::set<Replacement> Replacements; + +/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite. +/// +/// Replacement applications happen independently of the success of +/// other applications. +/// +/// \returns true if all replacements apply. false otherwise. +bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite); /// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite. /// @@ -111,7 +149,48 @@ typedef std::set<Replacement, Replacement::Less> Replacements; /// other applications. /// /// \returns true if all replacements apply. false otherwise. -bool applyAllReplacements(Replacements &Replaces, Rewriter &Rewrite); +bool applyAllReplacements(const std::vector<Replacement> &Replaces, + Rewriter &Rewrite); + +/// \brief Applies all replacements in \p Replaces to \p Code. +/// +/// This completely ignores the path stored in each replacement. If one or more +/// replacements cannot be applied, this returns an empty \c string. +std::string applyAllReplacements(StringRef Code, const Replacements &Replaces); + +/// \brief Calculates how a code \p Position is shifted when \p Replaces are +/// applied. +unsigned shiftedCodePosition(const Replacements& Replaces, unsigned Position); + +/// \brief Calculates how a code \p Position is shifted when \p Replaces are +/// applied. +/// +/// \pre Replaces[i].getOffset() <= Replaces[i+1].getOffset(). +unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces, + unsigned Position); + +/// \brief Removes duplicate Replacements and reports if Replacements conflict +/// with one another. +/// +/// \post Replaces[i].getOffset() <= Replaces[i+1].getOffset(). +/// +/// This function sorts \p Replaces so that conflicts can be reported simply by +/// offset into \p Replaces and number of elements in the conflict. +void deduplicate(std::vector<Replacement> &Replaces, + std::vector<Range> &Conflicts); + +/// \brief Collection of Replacements generated from a single translation unit. +struct TranslationUnitReplacements { + /// Name of the main source for the translation unit. + std::string MainSourceFile; + + /// A freeform chunk of text to describe the context of the replacements. + /// Will be printed, for example, when detecting conflicts during replacement + /// deduplication. + std::string Context; + + std::vector<Replacement> Replacements; +}; /// \brief A tool to run refactorings. /// diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/ReplacementsYaml.h b/contrib/llvm/tools/clang/include/clang/Tooling/ReplacementsYaml.h new file mode 100644 index 0000000..18d3259 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Tooling/ReplacementsYaml.h @@ -0,0 +1,88 @@ +//===-- ReplacementsYaml.h -- Serialiazation for Replacements ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file defines the structure of a YAML document for serializing +/// replacements. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REPLACEMENTS_YAML_H +#define LLVM_CLANG_TOOLING_REPLACEMENTS_YAML_H + +#include "clang/Tooling/Refactoring.h" +#include "llvm/Support/YAMLTraits.h" +#include <vector> +#include <string> + +LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Replacement) + +namespace llvm { +namespace yaml { + +/// \brief ScalarTraits to read/write std::string objects. +template <> struct ScalarTraits<std::string> { + static void output(const std::string &Val, void *, llvm::raw_ostream &Out) { + Out << Val; + } + + static StringRef input(StringRef Scalar, void *, std::string &Val) { + Val = Scalar; + return StringRef(); + } +}; + +/// \brief Specialized MappingTraits to describe how a Replacement is +/// (de)serialized. +template <> struct MappingTraits<clang::tooling::Replacement> { + /// \brief Helper to (de)serialize a Replacement since we don't have direct + /// access to its data members. + struct NormalizedReplacement { + NormalizedReplacement(const IO &) + : FilePath(""), Offset(0), Length(0), ReplacementText("") {} + + NormalizedReplacement(const IO &, const clang::tooling::Replacement &R) + : FilePath(R.getFilePath()), Offset(R.getOffset()), + Length(R.getLength()), ReplacementText(R.getReplacementText()) {} + + clang::tooling::Replacement denormalize(const IO &) { + return clang::tooling::Replacement(FilePath, Offset, Length, + ReplacementText); + } + + std::string FilePath; + unsigned int Offset; + unsigned int Length; + std::string ReplacementText; + }; + + static void mapping(IO &Io, clang::tooling::Replacement &R) { + MappingNormalization<NormalizedReplacement, clang::tooling::Replacement> + Keys(Io, R); + Io.mapRequired("FilePath", Keys->FilePath); + Io.mapRequired("Offset", Keys->Offset); + Io.mapRequired("Length", Keys->Length); + Io.mapRequired("ReplacementText", Keys->ReplacementText); + } +}; + +/// \brief Specialized MappingTraits to describe how a +/// TranslationUnitReplacements is (de)serialized. +template <> struct MappingTraits<clang::tooling::TranslationUnitReplacements> { + static void mapping(IO &Io, + clang::tooling::TranslationUnitReplacements &Doc) { + Io.mapRequired("MainSourceFile", Doc.MainSourceFile); + Io.mapOptional("Context", Doc.Context, std::string()); + Io.mapRequired("Replacements", Doc.Replacements); + } +}; +} // end namespace yaml +} // end namespace llvm + +#endif // LLVM_CLANG_TOOLING_REPLACEMENTS_YAML_H diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h b/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h index 27e5a0a..de507a7 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h @@ -30,6 +30,7 @@ #ifndef LLVM_CLANG_TOOLING_TOOLING_H #define LLVM_CLANG_TOOLING_TOOLING_H +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" #include "clang/Driver/Util.h" @@ -53,11 +54,34 @@ class FrontendAction; namespace tooling { +/// \brief Interface to process a clang::CompilerInvocation. +/// +/// If your tool is based on FrontendAction, you should be deriving from +/// FrontendActionFactory instead. +class ToolAction { +public: + virtual ~ToolAction(); + + /// \brief Perform an action for an invocation. + virtual bool runInvocation(clang::CompilerInvocation *Invocation, + FileManager *Files, + DiagnosticConsumer *DiagConsumer) = 0; +}; + /// \brief Interface to generate clang::FrontendActions. -class FrontendActionFactory { +/// +/// Having a factory interface allows, for example, a new FrontendAction to be +/// created for each translation unit processed by ClangTool. This class is +/// also a ToolAction which uses the FrontendActions created by create() to +/// process each translation unit. +class FrontendActionFactory : public ToolAction { public: virtual ~FrontendActionFactory(); + /// \brief Invokes the compiler with a FrontendAction created by create(). + bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files, + DiagnosticConsumer *DiagConsumer); + /// \brief Returns a new clang::FrontendAction. /// /// The caller takes ownership of the returned action. @@ -66,7 +90,7 @@ public: /// \brief Returns a new FrontendActionFactory for a given type. /// -/// T must extend clang::FrontendAction. +/// T must derive from clang::FrontendAction. /// /// Example: /// FrontendActionFactory *Factory = @@ -74,12 +98,22 @@ public: template <typename T> FrontendActionFactory *newFrontendActionFactory(); -/// \brief Called at the end of each source file when used with -/// \c newFrontendActionFactory. -class EndOfSourceFileCallback { +/// \brief Callbacks called before and after each source file processed by a +/// FrontendAction created by the FrontedActionFactory returned by \c +/// newFrontendActionFactory. +class SourceFileCallbacks { public: - virtual ~EndOfSourceFileCallback() {} - virtual void run() = 0; + virtual ~SourceFileCallbacks() {} + + /// \brief Called before a source file is processed by a FrontEndAction. + /// \see clang::FrontendAction::BeginSourceFileAction + virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) { + return true; + } + + /// \brief Called after a source file is processed by a FrontendAction. + /// \see clang::FrontendAction::EndSourceFileAction + virtual void handleEndSource() {} }; /// \brief Returns a new FrontendActionFactory for any type that provides an @@ -95,7 +129,7 @@ public: /// newFrontendActionFactory(&Factory); template <typename FactoryT> inline FrontendActionFactory *newFrontendActionFactory( - FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback = NULL); + FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = NULL); /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. /// @@ -120,6 +154,26 @@ bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code, const std::vector<std::string> &Args, const Twine &FileName = "input.cc"); +/// \brief Builds an AST for 'Code'. +/// +/// \param Code C++ code. +/// \param FileName The file name which 'Code' will be mapped as. +/// +/// \return The resulting AST or null if an error occurred. +ASTUnit *buildASTFromCode(const Twine &Code, + const Twine &FileName = "input.cc"); + +/// \brief Builds an AST for 'Code' with additional flags. +/// +/// \param Code C++ code. +/// \param Args Additional flags to pass on. +/// \param FileName The file name which 'Code' will be mapped as. +/// +/// \return The resulting AST or null if an error occurred. +ASTUnit *buildASTFromCodeWithArgs(const Twine &Code, + const std::vector<std::string> &Args, + const Twine &FileName = "input.cc"); + /// \brief Utility to run a FrontendAction in a single clang invocation. class ToolInvocation { public: @@ -129,12 +183,25 @@ class ToolInvocation { /// uses its binary name (CommandLine[0]) to locate its builtin headers. /// Callers have to ensure that they are installed in a compatible location /// (see clang driver implementation) or mapped in via mapVirtualFile. - /// \param ToolAction The action to be executed. Class takes ownership. + /// \param FAction The action to be executed. Class takes ownership. /// \param Files The FileManager used for the execution. Class does not take /// ownership. - ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction, + ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *FAction, + FileManager *Files); + + /// \brief Create a tool invocation. + /// + /// \param CommandLine The command line arguments to clang. + /// \param Action The action to be executed. + /// \param Files The FileManager used for the execution. + ToolInvocation(ArrayRef<std::string> CommandLine, ToolAction *Action, FileManager *Files); + ~ToolInvocation(); + + /// \brief Set a \c DiagnosticConsumer to use during parsing. + void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer); + /// \brief Map a virtual file to be used while running the tool. /// /// \param FilePath The path at which the content will be mapped. @@ -154,10 +221,12 @@ class ToolInvocation { clang::CompilerInvocation *Invocation); std::vector<std::string> CommandLine; - OwningPtr<FrontendAction> ToolAction; + ToolAction *Action; + bool OwnsAction; FileManager *Files; // Maps <file name> -> <file content>. llvm::StringMap<StringRef> MappedFileContents; + DiagnosticConsumer *DiagConsumer; }; /// \brief Utility to run a FrontendAction over a set of files. @@ -165,8 +234,8 @@ class ToolInvocation { /// This class is written to be usable for command line utilities. /// By default the class uses ClangSyntaxOnlyAdjuster to modify /// command line arguments before the arguments are used to run -/// a frontend action. One could install another command line -/// arguments adjuster by call setArgumentsAdjuster() method. +/// a frontend action. One could install an additional command line +/// arguments adjuster by calling the appendArgumentsAdjuster() method. class ClangTool { public: /// \brief Constructs a clang tool to run over a list of files. @@ -178,7 +247,10 @@ class ClangTool { ClangTool(const CompilationDatabase &Compilations, ArrayRef<std::string> SourcePaths); - virtual ~ClangTool() {} + virtual ~ClangTool() { clearArgumentsAdjusters(); } + + /// \brief Set a \c DiagnosticConsumer to use during parsing. + void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer); /// \brief Map a virtual file to be used while running the tool. /// @@ -189,29 +261,45 @@ class ClangTool { /// \brief Install command line arguments adjuster. /// /// \param Adjuster Command line arguments adjuster. + // + /// FIXME: Function is deprecated. Use (clear/append)ArgumentsAdjuster instead. + /// Remove it once all callers are gone. void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster); - /// Runs a frontend action over all files specified in the command line. + /// \brief Append a command line arguments adjuster to the adjuster chain. + /// + /// \param Adjuster An argument adjuster, which will be run on the output of + /// previous argument adjusters. + void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster); + + /// \brief Clear the command line arguments adjuster chain. + void clearArgumentsAdjusters(); + + /// Runs an action over all files specified in the command line. /// - /// \param ActionFactory Factory generating the frontend actions. The function - /// takes ownership of this parameter. A new action is generated for every - /// processed translation unit. - virtual int run(FrontendActionFactory *ActionFactory); + /// \param Action Tool action. + int run(ToolAction *Action); + + /// \brief Create an AST for each file specified in the command line and + /// append them to ASTs. + int buildASTs(std::vector<ASTUnit *> &ASTs); /// \brief Returns the file manager used in the tool. /// /// The file manager is shared between all translation units. - FileManager &getFiles() { return Files; } + FileManager &getFiles() { return *Files; } private: // We store compile commands as pair (file name, compile command). std::vector< std::pair<std::string, CompileCommand> > CompileCommands; - FileManager Files; + llvm::IntrusiveRefCntPtr<FileManager> Files; // Contains a list of pairs (<file name>, <file content>). std::vector< std::pair<StringRef, StringRef> > MappedFileContents; - OwningPtr<ArgumentsAdjuster> ArgsAdjuster; + SmallVector<ArgumentsAdjuster *, 2> ArgsAdjusters; + + DiagnosticConsumer *DiagConsumer; }; template <typename T> @@ -226,23 +314,23 @@ FrontendActionFactory *newFrontendActionFactory() { template <typename FactoryT> inline FrontendActionFactory *newFrontendActionFactory( - FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback) { + FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) { class FrontendActionFactoryAdapter : public FrontendActionFactory { public: explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory, - EndOfSourceFileCallback *EndCallback) - : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {} + SourceFileCallbacks *Callbacks) + : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} virtual clang::FrontendAction *create() { - return new ConsumerFactoryAdaptor(ConsumerFactory, EndCallback); + return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks); } private: class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { public: ConsumerFactoryAdaptor(FactoryT *ConsumerFactory, - EndOfSourceFileCallback *EndCallback) - : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {} + SourceFileCallbacks *Callbacks) + : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &, StringRef) { @@ -250,21 +338,29 @@ inline FrontendActionFactory *newFrontendActionFactory( } protected: - virtual void EndSourceFileAction() { - if (EndCallback != NULL) - EndCallback->run(); + virtual bool BeginSourceFileAction(CompilerInstance &CI, + StringRef Filename) LLVM_OVERRIDE { + if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename)) + return false; + if (Callbacks != NULL) + return Callbacks->handleBeginSource(CI, Filename); + return true; + } + virtual void EndSourceFileAction() LLVM_OVERRIDE { + if (Callbacks != NULL) + Callbacks->handleEndSource(); clang::ASTFrontendAction::EndSourceFileAction(); } private: FactoryT *ConsumerFactory; - EndOfSourceFileCallback *EndCallback; + SourceFileCallbacks *Callbacks; }; FactoryT *ConsumerFactory; - EndOfSourceFileCallback *EndCallback; + SourceFileCallbacks *Callbacks; }; - return new FrontendActionFactoryAdapter(ConsumerFactory, EndCallback); + return new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks); } /// \brief Returns the absolute path of \c File, by prepending it with @@ -275,10 +371,8 @@ inline FrontendActionFactory *newFrontendActionFactory( /// Otherwise, the returned path will contain the literal path-concatenation of /// the current directory and \c File. /// -/// The difference to llvm::sys::fs::make_absolute is that we prefer -/// ::getenv("PWD") if available. -/// FIXME: Make this functionality available from llvm::sys::fs and delete -/// this function. +/// The difference to llvm::sys::fs::make_absolute is the canonicalization this +/// does by removing "./" and computing native paths. /// /// \param File Either an absolute or relative path. std::string getAbsolutePath(StringRef File); |