diff options
author | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
commit | 9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch) | |
tree | c978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/tools/clang/include | |
parent | 03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff) | |
download | FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz |
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports
all of the features in the current working draft of the upcoming C++
standard, provisionally named C++1y.
The code generator's performance is greatly increased, and the loop
auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The
PowerPC backend has made several major improvements to code generation
quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ
backends have all seen major feature work.
Release notes for llvm and clang can be found here:
<http://llvm.org/releases/3.4/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html>
MFC 262121 (by emaste):
Update lldb for clang/llvm 3.4 import
This commit largely restores the lldb source to the upstream r196259
snapshot with the addition of threaded inferior support and a few bug
fixes.
Specific upstream lldb revisions restored include:
SVN git
181387 779e6ac
181703 7bef4e2
182099 b31044e
182650 f2dcf35
182683 0d91b80
183862 15c1774
183929 99447a6
184177 0b2934b
184948 4dc3761
184954 007e7bc
186990 eebd175
Sponsored by: DARPA, AFRL
MFC 262186 (by emaste):
Fix mismerge in r262121
A break statement was lost in the merge. The error had no functional
impact, but restore it to reduce the diff against upstream.
MFC 262303:
Pull in r197521 from upstream clang trunk (by rdivacky):
Use the integrated assembler by default on FreeBSD/ppc and ppc64.
Requested by: jhibbits
MFC 262611:
Pull in r196874 from upstream llvm trunk:
Fix a crash that occurs when PWD is invalid.
MCJIT needs to be able to run in hostile environments, even when PWD
is invalid. There's no need to crash MCJIT in this case.
The obvious fix is to simply leave MCContext's CompilationDir empty
when PWD can't be determined. This way, MCJIT clients,
and other clients that link with LLVM don't need a valid working directory.
If we do want to guarantee valid CompilationDir, that should be done
only for clients of getCompilationDir(). This is as simple as checking
for an empty string.
The only current use of getCompilationDir is EmitGenDwarfInfo, which
won't conceivably run with an invalid working dir. However, in the
purely hypothetically and untestable case that this happens, the
AT_comp_dir will be omitted from the compilation_unit DIE.
This should help fix assertions occurring with ports-mgmt/tinderbox,
when it is using jails, and sometimes invalidates clang's current
working directory.
Reported by: decke
MFC 262809:
Pull in r203007 from upstream clang trunk:
Don't produce an alias between destructors with different calling conventions.
Fixes pr19007.
(Please note that is an LLVM PR identifier, not a FreeBSD one.)
This should fix Firefox and/or libxul crashes (due to problems with
regparm/stdcall calling conventions) on i386.
Reported by: multiple users on freebsd-current
PR: bin/187103
MFC 263048:
Repair recognition of "CC" as an alias for the C++ compiler, since it
was silently broken by upstream for a Windows-specific use-case.
Apparently some versions of CMake still rely on this archaic feature...
Reported by: rakuco
MFC 263049:
Garbage collect the old way of adding the libstdc++ include directories
in clang's InitHeaderSearch.cpp. This has been superseded by David
Chisnall's commit in r255321.
Moreover, if libc++ is used, the libstdc++ include directories should
not be in the search path at all. These directories are now only used
if you pass -stdlib=libstdc++.
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); |