diff options
Diffstat (limited to 'include')
103 files changed, 3736 insertions, 663 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index cb0b3c1..4852ded 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -833,14 +833,24 @@ enum CXTranslationUnit_Flags { /** * \brief Used to indicate that the "detailed" preprocessing record, - * if requested, should also contain nested macro instantiations. + * if requested, should also contain nested macro expansions. * - * Nested macro instantiations (i.e., macro instantiations that occur - * inside another macro instantiation) can, in some code bases, require + * Nested macro expansions (i.e., macro expansions that occur + * inside another macro expansion) can, in some code bases, require * a large amount of storage to due preprocessor metaprogramming. Moreover, * its fairly rare that this information is useful for libclang clients. */ - CXTranslationUnit_NestedMacroInstantiations = 0x40 + CXTranslationUnit_NestedMacroExpansions = 0x40, + + /** + * \brief Legacy name to indicate that the "detailed" preprocessing record, + * if requested, should contain nested macro expansions. + * + * \see CXTranslationUnit_NestedMacroExpansions for the current name for this + * value, and its semantics. This is just an alias. + */ + CXTranslationUnit_NestedMacroInstantiations = + CXTranslationUnit_NestedMacroExpansions }; /** @@ -933,6 +943,41 @@ enum CXSaveTranslationUnit_Flags { CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU); /** + * \brief Describes the kind of error that occurred (if any) in a call to + * \c clang_saveTranslationUnit(). + */ +enum CXSaveError { + /** + * \brief Indicates that no error occurred while saving a translation unit. + */ + CXSaveError_None = 0, + + /** + * \brief Indicates that an unknown error occurred while attempting to save + * the file. + * + * This error typically indicates that file I/O failed when attempting to + * write the file. + */ + CXSaveError_Unknown = 1, + + /** + * \brief Indicates that errors during translation prevented this attempt + * to save the translation unit. + * + * Errors that prevent the translation unit from being saved can be + * extracted using \c clang_getNumDiagnostics() and \c clang_getDiagnostic(). + */ + CXSaveError_TranslationErrors = 2, + + /** + * \brief Indicates that the translation unit to be saved was somehow + * invalid (e.g., NULL). + */ + CXSaveError_InvalidTU = 3 +}; + +/** * \brief Saves a translation unit into a serialized representation of * that translation unit on disk. * @@ -951,8 +996,9 @@ CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU); * is saved. This should be a bitwise OR of the * CXSaveTranslationUnit_XXX flags. * - * \returns Zero if the translation unit was saved successfully, a - * non-zero value otherwise. + * \returns A value that will match one of the enumerators of the CXSaveError + * enumeration. Zero (CXSaveError_None) indicates that the translation unit was + * saved successfully, while a non-zero value indicates that a problem occurred. */ CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, @@ -1385,7 +1431,8 @@ enum CXCursorKind { /* Preprocessing */ CXCursor_PreprocessingDirective = 500, CXCursor_MacroDefinition = 501, - CXCursor_MacroInstantiation = 502, + CXCursor_MacroExpansion = 502, + CXCursor_MacroInstantiation = CXCursor_MacroExpansion, CXCursor_InclusionDirective = 503, CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective, CXCursor_LastPreprocessing = CXCursor_InclusionDirective @@ -1474,6 +1521,11 @@ CINDEX_LINKAGE unsigned clang_isExpression(enum CXCursorKind); CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind); /** + * \brief Determine whether the given cursor kind represents an attribute. + */ +CINDEX_LINKAGE unsigned clang_isAttribute(enum CXCursorKind); + +/** * \brief Determine whether the given cursor kind represents an invalid * cursor. */ @@ -2830,6 +2882,137 @@ enum CXCodeComplete_Flags { }; /** + * \brief Bits that represent the context under which completion is occurring. + * + * The enumerators in this enumeration may be bitwise-OR'd together if multiple + * contexts are occurring simultaneously. + */ +enum CXCompletionContext { + /** + * \brief The context for completions is unexposed, as only Clang results + * should be included. (This is equivalent to having no context bits set.) + */ + CXCompletionContext_Unexposed = 0, + + /** + * \brief Completions for any possible type should be included in the results. + */ + CXCompletionContext_AnyType = 1 << 0, + + /** + * \brief Completions for any possible value (variables, function calls, etc.) + * should be included in the results. + */ + CXCompletionContext_AnyValue = 1 << 1, + /** + * \brief Completions for values that resolve to an Objective-C object should + * be included in the results. + */ + CXCompletionContext_ObjCObjectValue = 1 << 2, + /** + * \brief Completions for values that resolve to an Objective-C selector + * should be included in the results. + */ + CXCompletionContext_ObjCSelectorValue = 1 << 3, + /** + * \brief Completions for values that resolve to a C++ class type should be + * included in the results. + */ + CXCompletionContext_CXXClassTypeValue = 1 << 4, + + /** + * \brief Completions for fields of the member being accessed using the dot + * operator should be included in the results. + */ + CXCompletionContext_DotMemberAccess = 1 << 5, + /** + * \brief Completions for fields of the member being accessed using the arrow + * operator should be included in the results. + */ + CXCompletionContext_ArrowMemberAccess = 1 << 6, + /** + * \brief Completions for properties of the Objective-C object being accessed + * using the dot operator should be included in the results. + */ + CXCompletionContext_ObjCPropertyAccess = 1 << 7, + + /** + * \brief Completions for enum tags should be included in the results. + */ + CXCompletionContext_EnumTag = 1 << 8, + /** + * \brief Completions for union tags should be included in the results. + */ + CXCompletionContext_UnionTag = 1 << 9, + /** + * \brief Completions for struct tags should be included in the results. + */ + CXCompletionContext_StructTag = 1 << 10, + + /** + * \brief Completions for C++ class names should be included in the results. + */ + CXCompletionContext_ClassTag = 1 << 11, + /** + * \brief Completions for C++ namespaces and namespace aliases should be + * included in the results. + */ + CXCompletionContext_Namespace = 1 << 12, + /** + * \brief Completions for C++ nested name specifiers should be included in + * the results. + */ + CXCompletionContext_NestedNameSpecifier = 1 << 13, + + /** + * \brief Completions for Objective-C interfaces (classes) should be included + * in the results. + */ + CXCompletionContext_ObjCInterface = 1 << 14, + /** + * \brief Completions for Objective-C protocols should be included in + * the results. + */ + CXCompletionContext_ObjCProtocol = 1 << 15, + /** + * \brief Completions for Objective-C categories should be included in + * the results. + */ + CXCompletionContext_ObjCCategory = 1 << 16, + /** + * \brief Completions for Objective-C instance messages should be included + * in the results. + */ + CXCompletionContext_ObjCInstanceMessage = 1 << 17, + /** + * \brief Completions for Objective-C class messages should be included in + * the results. + */ + CXCompletionContext_ObjCClassMessage = 1 << 18, + /** + * \brief Completions for Objective-C selector names should be included in + * the results. + */ + CXCompletionContext_ObjCSelectorName = 1 << 19, + + /** + * \brief Completions for preprocessor macro names should be included in + * the results. + */ + CXCompletionContext_MacroName = 1 << 20, + + /** + * \brief Natural language completions should be included in the results. + */ + CXCompletionContext_NaturalLanguage = 1 << 21, + + /** + * \brief The current context is unknown, so set all contexts. + */ + CXCompletionContext_Unknown = ((1 << 22) - 1) +}; + +/** * \brief Returns a default set of code-completion options that can be * passed to\c clang_codeCompleteAt(). */ @@ -2950,6 +3133,19 @@ CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results, unsigned Index); /** + * \brief Determines what compeltions are appropriate for the context + * the given code completion. + * + * \param Results the code completion results to query + * + * \returns the kinds of completions that are appropriate for use + * along with the given code completion results. + */ +CINDEX_LINKAGE +unsigned long long clang_codeCompleteGetContexts( + CXCodeCompleteResults *Results); + +/** * @} */ @@ -3005,6 +3201,51 @@ CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu, * @} */ +/** \defgroup CINDEX_REMAPPING Remapping functions + * + * @{ + */ + +/** + * \brief A remapping of original source files and their translated files. + */ +typedef void *CXRemapping; + +/** + * \brief Retrieve a remapping. + * + * \param path the path that contains metadata about remappings. + * + * \returns the requested remapping. This remapping must be freed + * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred. + */ +CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *path); + +/** + * \brief Determine the number of remappings. + */ +CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping); + +/** + * \brief Get the original and the associated filename from the remapping. + * + * \param original If non-NULL, will be set to the original filename. + * + * \param transformed If non-NULL, will be set to the filename that the original + * is associated with. + */ +CINDEX_LINKAGE void clang_remap_getFilenames(CXRemapping, unsigned index, + CXString *original, CXString *transformed); + +/** + * \brief Dispose the remapping. + */ +CINDEX_LINKAGE void clang_remap_dispose(CXRemapping); + +/** + * @} + */ + /** * @} */ diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h new file mode 100644 index 0000000..ad5cf4a --- /dev/null +++ b/include/clang/ARCMigrate/ARCMT.h @@ -0,0 +1,94 @@ +//===-- ARCMT.h - ARC Migration Rewriter ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_H +#define LLVM_CLANG_ARCMIGRATE_ARCMT_H + +#include "clang/ARCMigrate/FileRemapper.h" +#include "clang/Frontend/CompilerInvocation.h" + +namespace clang { + class ASTContext; + class DiagnosticClient; + +namespace arcmt { + class MigrationPass; + +/// \brief Creates an AST with the provided CompilerInvocation but with these +/// changes: +/// -if a PCH/PTH is set, the original header is used instead +/// -Automatic Reference Counting mode is enabled +/// +/// It then checks the AST and produces errors/warning for ARC migration issues +/// that the user needs to handle manually. +/// +/// \returns false if no error is produced, true otherwise. +bool checkForManualIssues(CompilerInvocation &CI, + llvm::StringRef Filename, InputKind Kind, + DiagnosticClient *DiagClient); + +/// \brief Works similar to checkForManualIssues but instead of checking, it +/// applies automatic modifications to source files to conform to ARC. +/// +/// \returns false if no error is produced, true otherwise. +bool applyTransformations(CompilerInvocation &origCI, + llvm::StringRef Filename, InputKind Kind, + DiagnosticClient *DiagClient); + +/// \brief Applies automatic modifications and produces temporary files +/// and metadata into the \arg outputDir path. +/// +/// \returns false if no error is produced, true otherwise. +bool migrateWithTemporaryFiles(CompilerInvocation &origCI, + llvm::StringRef Filename, InputKind Kind, + DiagnosticClient *DiagClient, + llvm::StringRef outputDir); + +/// \brief Get the set of file remappings from the \arg outputDir path that +/// migrateWithTemporaryFiles produced. +/// +/// \returns false if no error is produced, true otherwise. +bool getFileRemappings(std::vector<std::pair<std::string,std::string> > &remap, + llvm::StringRef outputDir, + DiagnosticClient *DiagClient); + +typedef void (*TransformFn)(MigrationPass &pass); + +std::vector<TransformFn> getAllTransformations(); + +class MigrationProcess { + CompilerInvocation OrigCI; + DiagnosticClient *DiagClient; + FileRemapper Remapper; + +public: + MigrationProcess(const CompilerInvocation &CI, DiagnosticClient *diagClient, + llvm::StringRef outputDir = llvm::StringRef()); + + class RewriteListener { + public: + virtual ~RewriteListener(); + + virtual void start(ASTContext &Ctx) { } + virtual void finish() { } + + virtual void insert(SourceLocation loc, llvm::StringRef text) { } + virtual void remove(CharSourceRange range) { } + }; + + bool applyTransform(TransformFn trans, RewriteListener *listener = 0); + + FileRemapper &getRemapper() { return Remapper; } +}; + +} // end namespace arcmt + +} // end namespace clang + +#endif diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h new file mode 100644 index 0000000..4c714f5 --- /dev/null +++ b/include/clang/ARCMigrate/ARCMTActions.h @@ -0,0 +1,47 @@ +//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H +#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H + +#include "clang/Frontend/FrontendAction.h" +#include "llvm/ADT/OwningPtr.h" + +namespace clang { +namespace arcmt { + +class CheckAction : public WrapperFrontendAction { +protected: + virtual bool BeginInvocation(CompilerInstance &CI); + +public: + CheckAction(FrontendAction *WrappedAction); +}; + +class ModifyAction : public WrapperFrontendAction { +protected: + virtual bool BeginInvocation(CompilerInstance &CI); + +public: + ModifyAction(FrontendAction *WrappedAction); +}; + +class MigrateAction : public WrapperFrontendAction { + std::string MigrateDir; +protected: + virtual bool BeginInvocation(CompilerInstance &CI); + +public: + MigrateAction(FrontendAction *WrappedAction, llvm::StringRef migrateDir); +}; + +} +} + +#endif diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h new file mode 100644 index 0000000..809f6a5 --- /dev/null +++ b/include/clang/ARCMigrate/FileRemapper.h @@ -0,0 +1,76 @@ +//===-- FileRemapper.h - File Remapping Helper ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H +#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" + +namespace llvm { + class MemoryBuffer; +} + +namespace clang { + class FileManager; + class FileEntry; + class Diagnostic; + class CompilerInvocation; + +namespace arcmt { + +class FileRemapper { + // FIXME: Reuse the same FileManager for multiple ASTContexts. + llvm::OwningPtr<FileManager> FileMgr; + + typedef llvm::PointerUnion<const FileEntry *, llvm::MemoryBuffer *> Target; + typedef llvm::DenseMap<const FileEntry *, Target> MappingsTy; + MappingsTy FromToMappings; + + llvm::DenseMap<const FileEntry *, const FileEntry *> ToFromMappings; + +public: + FileRemapper(); + ~FileRemapper(); + + bool initFromDisk(llvm::StringRef outputDir, Diagnostic &Diag, + bool ignoreIfFilesChanged); + bool flushToDisk(llvm::StringRef outputDir, Diagnostic &Diag); + + bool overwriteOriginal(Diagnostic &Diag, + llvm::StringRef outputDir = llvm::StringRef()); + + void remap(llvm::StringRef filePath, llvm::MemoryBuffer *memBuf); + void remap(llvm::StringRef filePath, llvm::StringRef newPath); + + void applyMappings(CompilerInvocation &CI) const; + + void transferMappingsAndClear(CompilerInvocation &CI); + + void clear(llvm::StringRef outputDir = llvm::StringRef()); + +private: + void remap(const FileEntry *file, llvm::MemoryBuffer *memBuf); + void remap(const FileEntry *file, const FileEntry *newfile); + + const FileEntry *getOriginalFile(llvm::StringRef filePath); + void resetTarget(Target &targ); + + bool report(const std::string &err, Diagnostic &Diag); + + std::string getRemapInfoFile(llvm::StringRef outputDir); +}; + +} // end namespace arcmt + +} // end namespace clang + +#endif diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 517c25d..1526f36 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -124,7 +124,10 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> { mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames; mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames; - mutable llvm::FoldingSet<SubstTemplateTemplateParmPackStorage> + mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage> + SubstTemplateTemplateParms; + mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage, + ASTContext&> SubstTemplateTemplateParmPacks; /// \brief The set of nested name specifiers. @@ -993,6 +996,18 @@ public: return getExtQualType(T, Qs); } + /// getLifetimeQualifiedType - Returns a type with the given + /// lifetime qualifier. + QualType getLifetimeQualifiedType(QualType type, + Qualifiers::ObjCLifetime lifetime) { + assert(type.getObjCLifetime() == Qualifiers::OCL_None); + assert(lifetime != Qualifiers::OCL_None); + + Qualifiers qs; + qs.addObjCLifetime(lifetime); + return getQualifiedType(type, qs); + } + DeclarationNameInfo getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const; @@ -1007,6 +1022,8 @@ public: const IdentifierInfo *Name) const; TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, OverloadedOperatorKind Operator) const; + TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param, + TemplateName replacement) const; TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, const TemplateArgument &ArgPack) const; @@ -1044,7 +1061,9 @@ public: /// isObjCNSObjectType - Return true if this is an NSObject object with /// its NSObject attribute set. - bool isObjCNSObjectType(QualType Ty) const; + static bool isObjCNSObjectType(QualType Ty) { + return Ty->isObjCNSObjectType(); + } //===--------------------------------------------------------------------===// // Type Sizing and Analysis @@ -1315,6 +1334,18 @@ public: /// getConstantArrayElementCount - Returns number of constant array elements. uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const; + /// \brief Perform adjustment on the parameter type of a function. + /// + /// This routine adjusts the given parameter type @p T to the actual + /// parameter type used by semantic analysis (C99 6.7.5.3p[7,8], + /// C++ [dcl.fct]p3). The adjusted parameter type is returned. + QualType getAdjustedParameterType(QualType T); + + /// \brief Retrieve the parameter type as adjusted for use in the signature + /// of a function, decaying array and function types and removing top-level + /// cv-qualifiers. + QualType getSignatureParameterType(QualType T); + /// getArrayDecayedType - Return the properly qualified result of decaying the /// specified array type to a pointer. This operation is non-trivial when /// handling typedefs etc. The canonical type of "T" must be an array type, @@ -1328,6 +1359,10 @@ public: /// integer type. QualType getPromotedIntegerType(QualType PromotableType) const; + /// \brief Recurses in pointer/array types until it finds an objc retainable + /// type and returns its ownership. + Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const; + /// \brief Whether this is a promotable bitfield reference according /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions). /// @@ -1382,6 +1417,7 @@ public: bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified = false); // C99 6.2.7p1 + bool propertyTypesAreCompatible(QualType, QualType); bool typesAreBlockPointerCompatible(QualType, QualType); bool isObjCIdType(QualType T) const { diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h index 1cb803a..70a548d 100644 --- a/include/clang/AST/ASTDiagnostic.h +++ b/include/clang/AST/ASTDiagnostic.h @@ -33,16 +33,18 @@ namespace clang { /// diagnostics. It is meant to be used as the argument to /// \c Diagnostic::SetArgToStringFn(), where the cookie is an \c ASTContext /// pointer. - void FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind, - intptr_t Val, - const char *Modifier, - unsigned ModLen, - const char *Argument, - unsigned ArgLen, - const Diagnostic::ArgumentValue *PrevArgs, - unsigned NumPrevArgs, - llvm::SmallVectorImpl<char> &Output, - void *Cookie); + void FormatASTNodeDiagnosticArgument( + Diagnostic::ArgumentKind Kind, + intptr_t Val, + const char *Modifier, + unsigned ModLen, + const char *Argument, + unsigned ArgLen, + const Diagnostic::ArgumentValue *PrevArgs, + unsigned NumPrevArgs, + llvm::SmallVectorImpl<char> &Output, + void *Cookie, + llvm::SmallVectorImpl<intptr_t> &QualTypeVals); } // end namespace clang #endif diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 2518814..38e6b41 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -250,7 +250,6 @@ public: LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPODType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType) @@ -295,6 +294,7 @@ public: LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl) /// \brief Retrieve the proxy-adaptor type. /// diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index d993d34..5691e99 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -702,8 +702,12 @@ private: /// \brief Whether this variable is the for-range-declaration in a C++0x /// for-range statement. unsigned CXXForRangeDecl : 1; + + /// \brief Whether this variable is an ARC pseudo-__strong + /// variable; see isARCPseudoStrong() for details. + unsigned ARCPseudoStrong : 1; }; - enum { NumVarDeclBits = 13 }; // two reserved bits for now + enum { NumVarDeclBits = 13 }; // one reserved bit friend class ASTDeclReader; friend class StmtIteratorBase; @@ -975,6 +979,20 @@ 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; + EvaluatedStmt *EnsureEvaluatedStmt() const { EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>(); if (!Eval) { @@ -1102,6 +1120,13 @@ public: /// a C++0x for-range statement. bool isCXXForRangeDecl() const { return VarDeclBits.CXXForRangeDecl; } void setCXXForRangeDecl(bool FRD) { VarDeclBits.CXXForRangeDecl = FRD; } + + /// \brief Determine whether this variable is an ARC pseudo-__strong + /// variable. A pseudo-__strong variable has a __strong-qualified + /// type but does not actually retain the object written into it. + /// Generally such variables are also 'const' for safety. + bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; } + void setARCPseudoStrong(bool ps) { VarDeclBits.ARCPseudoStrong = ps; } /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member @@ -2014,6 +2039,11 @@ public: InitializerOrBitWidth.setPointer(BW); InitializerOrBitWidth.setInt(1); } + /// removeBitWidth - Remove the bitfield width from this member. + void removeBitWidth() { + assert(isBitField() && "no bit width to remove"); + InitializerOrBitWidth.setPointer(0); + } /// hasInClassInitializer - Determine whether this member has a C++0x in-class /// initializer. @@ -2956,6 +2986,8 @@ public: bool capturesCXXThis() const { return CapturesCXXThis; } + bool capturesVariable(const VarDecl *var) const; + void setCaptures(ASTContext &Context, const Capture *begin, const Capture *end, diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index b5047b9..8b2ef2a 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -381,7 +381,24 @@ public: attr_iterator attr_end() const { return hasAttrs() ? getAttrs().end() : 0; } - + + template <typename T> + void dropAttr() { + if (!HasAttrs) return; + + AttrVec &Attrs = getAttrs(); + for (unsigned i = 0, e = Attrs.size(); i != e; /* in loop */) { + if (isa<T>(Attrs[i])) { + Attrs.erase(Attrs.begin() + i); + --e; + } + else + ++i; + } + if (Attrs.empty()) + HasAttrs = false; + } + template <typename T> specific_attr_iterator<T> specific_attr_begin() const { return specific_attr_iterator<T>(attr_begin()); diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 42a12eb..dd490f4 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -19,7 +19,6 @@ #include "clang/AST/Decl.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/UnresolvedSet.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" namespace clang { diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 74ceb43..d318fc2 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -641,6 +641,18 @@ public: return false; } + /// isArcWeakrefUnavailable - Checks for a class or one of its super classes + /// to be incompatible with __weak references. Returns true if it is. + bool isArcWeakrefUnavailable() const { + const ObjCInterfaceDecl *Class = this; + while (Class) { + if (Class->hasAttr<ArcWeakrefUnavailableAttr>()) + return true; + Class = Class->getSuperClass(); + } + return false; + } + ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared); ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) { @@ -1240,6 +1252,9 @@ class ObjCImplementationDecl : public ObjCImplDecl { /// IvarInitializers - The arguments used to initialize the ivars CXXCtorInitializer **IvarInitializers; unsigned NumIvarInitializers; + + /// true if class has a .cxx_[construct,destruct] method. + bool HasCXXStructors : 1; /// true of class extension has at least one bitfield ivar. bool HasSynthBitfield : 1; @@ -1249,7 +1264,7 @@ class ObjCImplementationDecl : public ObjCImplDecl { ObjCInterfaceDecl *superDecl) : ObjCImplDecl(ObjCImplementation, DC, L, classInterface), SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0), - HasSynthBitfield(false) {} + HasCXXStructors(false), HasSynthBitfield(false) {} public: static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, @@ -1287,6 +1302,9 @@ public: void setIvarInitializers(ASTContext &C, CXXCtorInitializer ** initializers, unsigned numInitializers); + + bool hasCXXStructors() const { return HasCXXStructors; } + void setHasCXXStructors(bool val) { HasCXXStructors = val; } bool hasSynthBitfield() const { return HasSynthBitfield; } void setHasSynthBitfield (bool val) { HasSynthBitfield = val; } @@ -1393,7 +1411,16 @@ public: OBJC_PR_copy = 0x20, OBJC_PR_nonatomic = 0x40, OBJC_PR_setter = 0x80, - OBJC_PR_atomic = 0x100 + OBJC_PR_atomic = 0x100, + OBJC_PR_weak = 0x200, + OBJC_PR_strong = 0x400, + OBJC_PR_unsafe_unretained = 0x800 + // Adding a property should change NumPropertyAttrsBits + }; + + enum { + /// \brief Number of bits fitting all the property attributes. + NumPropertyAttrsBits = 12 }; enum SetterKind { Assign, Retain, Copy }; @@ -1401,8 +1428,8 @@ public: private: SourceLocation AtLoc; // location of @property TypeSourceInfo *DeclType; - unsigned PropertyAttributes : 9; - unsigned PropertyAttributesAsWritten : 9; + unsigned PropertyAttributes : NumPropertyAttrsBits; + unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; // @required/@optional unsigned PropertyImplementation : 2; @@ -1445,6 +1472,12 @@ public: PropertyAttributeKind getPropertyAttributesAsWritten() const { return PropertyAttributeKind(PropertyAttributesAsWritten); } + + bool hasWrittenStorageAttribute() const { + return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy | + OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong | + OBJC_PR_weak); + } void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { PropertyAttributesAsWritten = PRVal; @@ -1466,7 +1499,7 @@ public: /// the property setter. This is only valid if the property has been /// defined to have a setter. SetterKind getSetterKind() const { - if (PropertyAttributes & OBJC_PR_retain) + if (PropertyAttributes & (OBJC_PR_retain|OBJC_PR_strong)) return Retain; if (PropertyAttributes & OBJC_PR_copy) return Copy; diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index dc50d61..d2b1d39 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -314,6 +314,10 @@ public: return (TemplateSpecializationKind)(Template.getInt() + 1); } + bool isExplicitSpecialization() const { + return getTemplateSpecializationKind() == TSK_ExplicitSpecialization; + } + /// \brief Set the template specialization kind. void setTemplateSpecializationKind(TemplateSpecializationKind TSK) { assert(TSK != TSK_Undeclared && @@ -1398,6 +1402,10 @@ public: return static_cast<TemplateSpecializationKind>(SpecializationKind); } + bool isExplicitSpecialization() const { + return getSpecializationKind() == TSK_ExplicitSpecialization; + } + void setSpecializationKind(TemplateSpecializationKind TSK) { SpecializationKind = TSK; } diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index e54719b..bb09831 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -492,6 +492,9 @@ public: LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding(); } + /// \brief Determine whether this name involves a template parameter. + bool isInstantiationDependent() const; + /// \brief Determine whether this name contains an unexpanded /// parameter pack. bool containsUnexpandedParameterPack() const; diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index ce86458e..c7f8707 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -57,9 +57,12 @@ class Expr : public Stmt { protected: Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, - bool TD, bool VD, bool ContainsUnexpandedParameterPack) : Stmt(SC) { + bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack) + : Stmt(SC) + { ExprBits.TypeDependent = TD; ExprBits.ValueDependent = VD; + ExprBits.InstantiationDependent = ID; ExprBits.ValueKind = VK; ExprBits.ObjectKind = OK; ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; @@ -95,7 +98,11 @@ public: bool isValueDependent() const { return ExprBits.ValueDependent; } /// \brief Set whether this expression is value-dependent or not. - void setValueDependent(bool VD) { ExprBits.ValueDependent = VD; } + void setValueDependent(bool VD) { + ExprBits.ValueDependent = VD; + if (VD) + ExprBits.InstantiationDependent = true; + } /// isTypeDependent - Determines whether this expression is /// type-dependent (C++ [temp.dep.expr]), which means that its type @@ -111,7 +118,37 @@ public: bool isTypeDependent() const { return ExprBits.TypeDependent; } /// \brief Set whether this expression is type-dependent or not. - void setTypeDependent(bool TD) { ExprBits.TypeDependent = TD; } + void setTypeDependent(bool TD) { + ExprBits.TypeDependent = TD; + if (TD) + ExprBits.InstantiationDependent = true; + } + + /// \brief Whether this expression is instantiation-dependent, meaning that + /// it depends in some way on a template parameter, even if neither its type + /// nor (constant) value can change due to the template instantiation. + /// + /// In the following example, the expression \c sizeof(sizeof(T() + T())) is + /// instantiation-dependent (since it involves a template parameter \c T), but + /// is neither type- nor value-dependent, since the type of the inner + /// \c sizeof is known (\c std::size_t) and therefore the size of the outer + /// \c sizeof is known. + /// + /// \code + /// template<typename T> + /// void f(T x, T y) { + /// sizeof(sizeof(T() + T()); + /// } + /// \endcode + /// + bool isInstantiationDependent() const { + return ExprBits.InstantiationDependent; + } + + /// \brief Set whether this expression is instantiation-dependent or not. + void setInstantiationDependent(bool ID) { + ExprBits.InstantiationDependent = ID; + } /// \brief Whether this expression contains an unexpanded parameter /// pack (for C++0x variadic templates). @@ -501,6 +538,14 @@ public: /// the rules of C++ [expr.unary.noexcept]. CanThrowResult CanThrow(ASTContext &C) const; + /// IgnoreImpCasts - Skip past any implicit casts which might + /// surround this expression. Only skips ImplicitCastExprs. + Expr *IgnoreImpCasts(); + + /// IgnoreImplicit - Skip past any implicit AST nodes which might + /// surround this expression. + Expr *IgnoreImplicit() { return cast<Expr>(Stmt::IgnoreImplicit()); } + /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return /// its subexpression. If that subexpression is also a ParenExpr, /// then this method recursively returns its subexpression, and so forth. @@ -555,7 +600,10 @@ public: /// \brief Whether this expression is an implicit reference to 'this' in C++. bool isImplicitCXXThis() const; - + + const Expr *IgnoreImpCasts() const { + return const_cast<Expr*>(this)->IgnoreImpCasts(); + } const Expr *IgnoreParens() const { return const_cast<Expr*>(this)->IgnoreParens(); } @@ -595,7 +643,9 @@ public: OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK, ExprObjectKind OK = OK_Ordinary) : Expr(OpaqueValueExprClass, T, VK, OK, - T->isDependentType(), T->isDependentType(), false), + T->isDependentType(), T->isDependentType(), + T->isInstantiationDependentType(), + false), SourceExpr(0), Loc(Loc) { } @@ -664,7 +714,8 @@ struct ExplicitTemplateArgumentList { void initializeFrom(const TemplateArgumentListInfo &List); void initializeFrom(const TemplateArgumentListInfo &List, - bool &Dependent, bool &ContainsUnexpandedParameterPack); + bool &Dependent, bool &InstantiationDependent, + bool &ContainsUnexpandedParameterPack); void copyInto(TemplateArgumentListInfo &List) const; static std::size_t sizeFor(unsigned NumTemplateArgs); static std::size_t sizeFor(const TemplateArgumentListInfo &List); @@ -746,9 +797,10 @@ class DeclRefExpr : public Expr { void computeDependence(); public: - DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L) - : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), - D(D), Loc(L) { + DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L, + const DeclarationNameLoc &LocInfo = DeclarationNameLoc()) + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), + D(D), Loc(L), DNLoc(LocInfo) { DeclRefExprBits.HasQualifier = 0; DeclRefExprBits.HasExplicitTemplateArgs = 0; DeclRefExprBits.HasFoundDecl = 0; @@ -936,6 +988,7 @@ public: PredefinedExpr(SourceLocation l, QualType type, IdentType IT) : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary, type->isDependentType(), type->isDependentType(), + type->isInstantiationDependentType(), /*ContainsUnexpandedParameterPack=*/false), Loc(l), Type(IT) {} @@ -1023,7 +1076,7 @@ public: IntegerLiteral(ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l) : Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Loc(l) { assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); assert(V.getBitWidth() == C.getIntWidth(type) && @@ -1066,7 +1119,7 @@ public: // type should be IntTy CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l) : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Value(value), Loc(l), IsWide(iswide) { } @@ -1101,7 +1154,7 @@ class FloatingLiteral : public Expr { FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false, - false), + false, false), IsExact(isexact), Loc(L) { setValue(C, V); } @@ -1152,7 +1205,7 @@ class ImaginaryLiteral : public Expr { public: ImaginaryLiteral(Expr *val, QualType Ty) : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Val(val) {} /// \brief Build an empty imaginary literal. @@ -1200,21 +1253,20 @@ class StringLiteral : public Expr { SourceLocation TokLocs[1]; StringLiteral(QualType Ty) : - Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false) {} + Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false, + false) {} public: /// This is the "fully general" constructor that allows representation of /// strings formed from multiple concatenated tokens. - static StringLiteral *Create(ASTContext &C, const char *StrData, - unsigned ByteLength, bool Wide, bool Pascal, - QualType Ty, + static StringLiteral *Create(ASTContext &C, llvm::StringRef Str, bool Wide, + bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs); /// Simple constructor for string literals made from one token. - static StringLiteral *Create(ASTContext &C, const char *StrData, - unsigned ByteLength, bool Wide, + static StringLiteral *Create(ASTContext &C, llvm::StringRef Str, bool Wide, bool Pascal, QualType Ty, SourceLocation Loc) { - return Create(C, StrData, ByteLength, Wide, Pascal, Ty, &Loc, 1); + return Create(C, Str, Wide, Pascal, Ty, &Loc, 1); } /// \brief Construct an empty string literal. @@ -1289,6 +1341,7 @@ public: : Expr(ParenExprClass, val->getType(), val->getValueKind(), val->getObjectKind(), val->isTypeDependent(), val->isValueDependent(), + val->isInstantiationDependent(), val->containsUnexpandedParameterPack()), L(l), R(r), Val(val) {} @@ -1345,6 +1398,8 @@ public: : Expr(UnaryOperatorClass, type, VK, OK, input->isTypeDependent() || type->isDependentType(), input->isValueDependent(), + (input->isInstantiationDependent() || + type->isInstantiationDependentType()), input->containsUnexpandedParameterPack()), Opc(opc), Loc(l), Val(input) {} @@ -1640,6 +1695,7 @@ public: false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. TInfo->getType()->isDependentType(), + TInfo->getType()->isInstantiationDependentType(), TInfo->getType()->containsUnexpandedParameterPack()), Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) { Argument.Ty = TInfo; @@ -1652,6 +1708,7 @@ public: false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. E->isTypeDependent(), + E->isInstantiationDependent(), E->containsUnexpandedParameterPack()), Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) { Argument.Ex = E; @@ -1729,6 +1786,8 @@ public: : Expr(ArraySubscriptExprClass, t, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), RBracketLoc(rbracketloc) { @@ -1986,7 +2045,9 @@ public: const DeclarationNameInfo &NameInfo, QualType ty, ExprValueKind VK, ExprObjectKind OK) : Expr(MemberExprClass, ty, VK, OK, - base->isTypeDependent(), base->isValueDependent(), + base->isTypeDependent(), + base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()), MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow), @@ -2003,6 +2064,7 @@ public: ExprValueKind VK, ExprObjectKind OK) : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(), IsArrow(isarrow), @@ -2188,6 +2250,8 @@ public: : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary, tinfo->getType()->isDependentType(), init->isValueDependent(), + (init->isInstantiationDependent() || + tinfo->getType()->isInstantiationDependentType()), init->containsUnexpandedParameterPack()), LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {} @@ -2276,6 +2340,9 @@ private: case CK_IntegralComplexToReal: case CK_IntegralComplexCast: case CK_IntegralComplexToFloatingComplex: + case CK_ObjCProduceObject: + case CK_ObjCConsumeObject: + case CK_ObjCReclaimReturnedObject: assert(!getType()->isBooleanType() && "unheralded conversion to bool"); // fallthrough to check for null base path @@ -2318,6 +2385,8 @@ protected: // Cast expressions are value-dependent if the type is // dependent or if the subexpression is value-dependent. ty->isDependentType() || (op && op->isValueDependent()), + (ty->isInstantiationDependentType() || + (op && op->isInstantiationDependent())), (ty->containsUnexpandedParameterPack() || op->containsUnexpandedParameterPack())), Op(op) { @@ -2426,6 +2495,13 @@ public: static bool classof(const ImplicitCastExpr *) { return true; } }; +inline Expr *Expr::IgnoreImpCasts() { + Expr *e = this; + while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e)) + e = ice->getSubExpr(); + return e; +} + /// ExplicitCastExpr - An explicit cast written in the source /// code. /// @@ -2551,6 +2627,8 @@ public: : Expr(BinaryOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), Opc(opc), OpLoc(opLoc) { @@ -2653,6 +2731,8 @@ protected: : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), Opc(opc), OpLoc(opLoc) { @@ -2713,11 +2793,11 @@ class AbstractConditionalOperator : public Expr { protected: AbstractConditionalOperator(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, - bool TD, bool VD, + bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack, SourceLocation qloc, SourceLocation cloc) - : Expr(SC, T, VK, OK, TD, VD, ContainsUnexpandedParameterPack), + : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack), QuestionLoc(qloc), ColonLoc(cloc) {} AbstractConditionalOperator(StmtClass SC, EmptyShell Empty) @@ -2765,6 +2845,9 @@ public: (lhs->isTypeDependent() || rhs->isTypeDependent()), (cond->isValueDependent() || lhs->isValueDependent() || rhs->isValueDependent()), + (cond->isInstantiationDependent() || + lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (cond->containsUnexpandedParameterPack() || lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack()), @@ -2833,6 +2916,8 @@ public: : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK, (common->isTypeDependent() || rhs->isTypeDependent()), (common->isValueDependent() || rhs->isValueDependent()), + (common->isInstantiationDependent() || + rhs->isInstantiationDependent()), (common->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack()), qloc, cloc), @@ -2914,7 +2999,8 @@ class AddrLabelExpr : public Expr { public: AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L, QualType t) - : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false), + : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false, + false), AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} /// \brief Build an empty address of a label expression. @@ -2953,10 +3039,12 @@ class StmtExpr : public Expr { SourceLocation LParenLoc, RParenLoc; public: // FIXME: Does type-dependence need to be computed differently? + // FIXME: Do we need to compute instantiation instantiation-dependence for + // statements? (ugh!) StmtExpr(CompoundStmt *substmt, QualType T, SourceLocation lp, SourceLocation rp) : Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, - T->isDependentType(), false, false), + T->isDependentType(), false, false, false), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } /// \brief Build an empty statement expression. @@ -3073,6 +3161,9 @@ public: QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation RP, bool TypeDependent, bool ValueDependent) : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent, + (cond->isInstantiationDependent() || + lhs->isInstantiationDependent() || + rhs->isInstantiationDependent()), (cond->containsUnexpandedParameterPack() || lhs->containsUnexpandedParameterPack() || rhs->containsUnexpandedParameterPack())), @@ -3134,7 +3225,8 @@ class GNUNullExpr : public Expr { public: GNUNullExpr(QualType Ty, SourceLocation Loc) - : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false), + : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false, + false), TokenLoc(Loc) { } /// \brief Build an empty GNU __null expression. @@ -3166,6 +3258,8 @@ public: SourceLocation RPLoc, QualType t) : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, t->isDependentType(), false, + (TInfo->getType()->isInstantiationDependentType() || + e->isInstantiationDependent()), (TInfo->getType()->containsUnexpandedParameterPack() || e->containsUnexpandedParameterPack())), Val(e), TInfo(TInfo), @@ -3537,9 +3631,9 @@ public: bool isArrayDesignator() const { return Kind == ArrayDesignator; } bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; } - IdentifierInfo * getFieldName(); + IdentifierInfo *getFieldName() const; - FieldDecl *getField() { + FieldDecl *getField() const { assert(Kind == FieldDesignator && "Only valid on a field designator"); if (Field.NameOrField & 0x01) return 0; @@ -3612,12 +3706,18 @@ public: unsigned size() const { return NumDesignators; } // Iterator access to the designators. - typedef Designator* designators_iterator; + typedef Designator *designators_iterator; designators_iterator designators_begin() { return Designators; } designators_iterator designators_end() { return Designators + NumDesignators; } + typedef const Designator *const_designators_iterator; + const_designators_iterator designators_begin() const { return Designators; } + const_designators_iterator designators_end() const { + return Designators + NumDesignators; + } + typedef std::reverse_iterator<designators_iterator> reverse_designators_iterator; reverse_designators_iterator designators_rbegin() { @@ -3627,6 +3727,15 @@ public: return reverse_designators_iterator(designators_begin()); } + typedef std::reverse_iterator<const_designators_iterator> + const_reverse_designators_iterator; + const_reverse_designators_iterator designators_rbegin() const { + return const_reverse_designators_iterator(designators_end()); + } + const_reverse_designators_iterator designators_rend() const { + return const_reverse_designators_iterator(designators_begin()); + } + Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; } void setDesignators(ASTContext &C, const Designator *Desigs, @@ -3708,7 +3817,7 @@ class ImplicitValueInitExpr : public Expr { public: explicit ImplicitValueInitExpr(QualType ty) : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, - false, false, false) { } + false, false, ty->isInstantiationDependentType(), false) { } /// \brief Construct an empty implicit value initialization. explicit ImplicitValueInitExpr(EmptyShell Empty) @@ -3735,7 +3844,7 @@ class ParenListExpr : public Expr { public: ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, - unsigned numexprs, SourceLocation rparenloc); + unsigned numexprs, SourceLocation rparenloc, QualType T); /// \brief Build an empty paren list. explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } @@ -3909,6 +4018,7 @@ public: : Expr(ExtVectorElementExprClass, ty, VK, (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent), base->isTypeDependent(), base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), Base(base), Accessor(&accessor), AccessorLoc(loc) {} @@ -3963,7 +4073,10 @@ protected: public: BlockExpr(BlockDecl *BD, QualType ty) : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary, - ty->isDependentType(), false, false), + ty->isDependentType(), false, + // FIXME: Check for instantiate-dependence in the statement? + ty->isInstantiationDependentType(), + false), TheBlock(BD) {} /// \brief Build an empty block expression. @@ -4037,26 +4150,36 @@ 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 { +class AsTypeExpr : public Expr { // Should this be an ExplicitCastExpr? private: - Expr* SrcExpr; - QualType DstType; + Stmt *SrcExpr; SourceLocation BuiltinLoc, RParenLoc; + + friend class ASTReader; + friend class ASTStmtReader; + explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {} public: AsTypeExpr(Expr* SrcExpr, QualType DstType, ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc, SourceLocation RParenLoc) - : Expr(AsTypeExprClass, DstType, VK, OK, false, false, false), - SrcExpr(SrcExpr), DstType(DstType), - BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} - - /// \brief Build an empty __builtin_astype - explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {} + : Expr(AsTypeExprClass, DstType, VK, OK, + DstType->isDependentType(), + DstType->isDependentType() || SrcExpr->isValueDependent(), + (DstType->isInstantiationDependentType() || + SrcExpr->isInstantiationDependent()), + (DstType->containsUnexpandedParameterPack() || + SrcExpr->containsUnexpandedParameterPack())), + SrcExpr(SrcExpr), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} /// getSrcExpr - Return the Expr to be converted. - Expr *getSrcExpr() const { return SrcExpr; } - QualType getDstType() const { return DstType; } + Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); } + + /// getBuiltinLoc - Return the location of the __builtin_astype token. + SourceLocation getBuiltinLoc() const { return BuiltinLoc; } + + /// getRParenLoc - Return the location of final right parenthesis. + SourceLocation getRParenLoc() const { return RParenLoc; } SourceRange getSourceRange() const { return SourceRange(BuiltinLoc, RParenLoc); @@ -4068,7 +4191,7 @@ public: static bool classof(const AsTypeExpr *) { return true; } // Iterators - child_range children() { return child_range(); } + child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } }; } // end namespace clang diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index a970579..1911704 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -330,7 +330,7 @@ class CXXBoolLiteralExpr : public Expr { public: CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Value(val), Loc(l) {} explicit CXXBoolLiteralExpr(EmptyShell Empty) @@ -359,7 +359,7 @@ class CXXNullPtrLiteralExpr : public Expr { public: CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false), + false, false), Loc(l) {} explicit CXXNullPtrLiteralExpr(EmptyShell Empty) @@ -395,6 +395,7 @@ public: false, // typeid is value-dependent if the type or expression are dependent Operand->getType()->isDependentType(), + Operand->getType()->isInstantiationDependentType(), Operand->getType()->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } @@ -404,6 +405,7 @@ public: false, // typeid is value-dependent if the type or expression are dependent Operand->isTypeDependent() || Operand->isValueDependent(), + Operand->isInstantiationDependent(), Operand->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } @@ -471,12 +473,14 @@ public: CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, Operand->getType()->isDependentType(), + Operand->getType()->isInstantiationDependentType(), Operand->getType()->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R) : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, Operand->isTypeDependent(), + Operand->isInstantiationDependent(), Operand->containsUnexpandedParameterPack()), Operand(Operand), Range(R) { } @@ -552,6 +556,7 @@ public: // 'this' is type-dependent if the class type of the enclosing // member function is dependent (C++ [temp.dep.expr]p2) Type->isDependentType(), Type->isDependentType(), + Type->isInstantiationDependentType(), /*ContainsUnexpandedParameterPack=*/false), Loc(L), Implicit(isImplicit) { } @@ -581,23 +586,35 @@ public: class CXXThrowExpr : public Expr { Stmt *Op; SourceLocation ThrowLoc; + /// \brief Whether the thrown variable (if any) is in scope. + unsigned IsThrownVariableInScope : 1; + + 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 // can by null, if the optional expression to throw isn't present. - CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) : + CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l, + bool IsThrownVariableInScope) : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false, + expr && expr->isInstantiationDependent(), expr && expr->containsUnexpandedParameterPack()), - Op(expr), ThrowLoc(l) {} + Op(expr), ThrowLoc(l), IsThrownVariableInScope(IsThrownVariableInScope) {} CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); } Expr *getSubExpr() { return cast_or_null<Expr>(Op); } - void setSubExpr(Expr *E) { Op = E; } SourceLocation getThrowLoc() const { return ThrowLoc; } - void setThrowLoc(SourceLocation L) { ThrowLoc = L; } + /// \brief Determines whether the variable thrown by this expression (if any!) + /// is within the innermost try block. + /// + /// This information is required to determine whether the NRVO can apply to + /// this variable. + bool isThrownVariableInScope() const { return IsThrownVariableInScope; } + SourceRange getSourceRange() const { if (getSubExpr() == 0) return SourceRange(ThrowLoc, ThrowLoc); @@ -636,14 +653,14 @@ class CXXDefaultArgExpr : public Expr { ? param->getType().getNonReferenceType() : param->getDefaultArg()->getType(), param->getDefaultArg()->getValueKind(), - param->getDefaultArg()->getObjectKind(), false, false, false), + param->getDefaultArg()->getObjectKind(), false, false, false, false), Param(param, false), Loc(Loc) { } CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, Expr *SubExpr) : Expr(SC, SubExpr->getType(), SubExpr->getValueKind(), SubExpr->getObjectKind(), - false, false, false), + false, false, false, false), Param(param, true), Loc(Loc) { *reinterpret_cast<Expr **>(this + 1) = SubExpr; } @@ -742,6 +759,7 @@ class CXXBindTemporaryExpr : public Expr { : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(), SubExpr->isValueDependent(), + SubExpr->isInstantiationDependent(), SubExpr->containsUnexpandedParameterPack()), Temp(temp), SubExpr(SubExpr) { } @@ -995,7 +1013,7 @@ public: TypeSourceInfo *TypeInfo, SourceLocation rParenLoc ) : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, - false, false, false), + false, false, Type->isInstantiationDependentType(), false), RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} explicit CXXScalarValueInitExpr(EmptyShell Shell) @@ -1241,6 +1259,7 @@ public: bool arrayFormAsWritten, bool usualArrayDeleteWantsSize, FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc) : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false, + arg->isInstantiationDependent(), arg->containsUnexpandedParameterPack()), GlobalDelete(globalDelete), ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten), @@ -1500,6 +1519,7 @@ public: SourceLocation rparen, QualType ty) : Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false, queried->getType()->isDependentType(), + queried->getType()->isInstantiationDependentType(), queried->getType()->containsUnexpandedParameterPack()), UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { } @@ -1558,6 +1578,8 @@ public: : Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false, lhsType->getType()->isDependentType() || rhsType->getType()->isDependentType(), + (lhsType->getType()->isInstantiationDependentType() || + rhsType->getType()->isInstantiationDependentType()), (lhsType->getType()->containsUnexpandedParameterPack() || rhsType->getType()->containsUnexpandedParameterPack())), BTT(btt), Value(value), Loc(loc), RParen(rparen), @@ -1625,6 +1647,8 @@ public: Expr *dimension, SourceLocation rparen, QualType ty) : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false, queried->getType()->isDependentType(), + (queried->getType()->isInstantiationDependentType() || + (dimension && dimension->isInstantiationDependent())), queried->getType()->containsUnexpandedParameterPack()), ATT(att), Value(value), Dimension(dimension), Loc(loc), RParen(rparen), QueriedType(queried) { } @@ -1684,6 +1708,7 @@ public: false, // Not type-dependent // Value-dependent if the argument is type-dependent. queried->isTypeDependent(), + queried->isInstantiationDependent(), queried->containsUnexpandedParameterPack()), ET(et), Value(value), Loc(loc), RParen(rparen), QueriedExpression(queried) { } @@ -1736,8 +1761,9 @@ protected: const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, - bool KnownDependent = false, - bool KnownContainsUnexpandedParameterPack = false); + bool KnownDependent, + bool KnownInstantiationDependent, + bool KnownContainsUnexpandedParameterPack); OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty), Results(0), NumResults(0), @@ -1880,7 +1906,7 @@ class UnresolvedLookupExpr : public OverloadExpr { UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool StdIsAssociatedNamespace) : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo, - TemplateArgs, Begin, End), + TemplateArgs, Begin, End, false, false, false), RequiresADL(RequiresADL), StdIsAssociatedNamespace(StdIsAssociatedNamespace), Overloaded(Overloaded), NamingClass(NamingClass) @@ -2727,6 +2753,7 @@ public: : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, /*TypeDependent*/false, /*ValueDependent*/Val == CT_Dependent, + Val == CT_Dependent || Operand->isInstantiationDependent(), Operand->containsUnexpandedParameterPack()), Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) { } @@ -2787,7 +2814,8 @@ public: llvm::Optional<unsigned> NumExpansions) : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), Pattern->getObjectKind(), /*TypeDependent=*/true, - /*ValueDependent=*/true, /*ContainsUnexpandedParameterPack=*/false), + /*ValueDependent=*/true, /*InstantiationDependent=*/true, + /*ContainsUnexpandedParameterPack=*/false), EllipsisLoc(EllipsisLoc), NumExpansions(NumExpansions? *NumExpansions + 1 : 0), Pattern(Pattern) { } @@ -2874,6 +2902,7 @@ public: SourceLocation PackLoc, SourceLocation RParenLoc) : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, /*TypeDependent=*/false, /*ValueDependent=*/true, + /*InstantiationDependent=*/true, /*ContainsUnexpandedParameterPack=*/false), OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), Length(0), Pack(Pack) { } @@ -2885,6 +2914,7 @@ public: unsigned Length) : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, /*TypeDependent=*/false, /*ValueDependent=*/false, + /*InstantiationDependent=*/false, /*ContainsUnexpandedParameterPack=*/false), OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), Length(Length), Pack(Pack) { } @@ -2927,6 +2957,53 @@ public: child_range children() { return child_range(); } }; +/// \brief Represents a reference to a non-type template parameter +/// that has been substituted with a template argument. +class SubstNonTypeTemplateParmExpr : public Expr { + /// \brief The replaced parameter. + NonTypeTemplateParmDecl *Param; + + /// \brief The replacement expression. + Stmt *Replacement; + + /// \brief The location of the non-type template parameter reference. + SourceLocation NameLoc; + + friend class ASTReader; + friend class ASTStmtReader; + explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty) + : Expr(SubstNonTypeTemplateParmExprClass, Empty) { } + +public: + SubstNonTypeTemplateParmExpr(QualType type, + ExprValueKind valueKind, + SourceLocation loc, + NonTypeTemplateParmDecl *param, + Expr *replacement) + : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary, + replacement->isTypeDependent(), replacement->isValueDependent(), + replacement->isInstantiationDependent(), + replacement->containsUnexpandedParameterPack()), + Param(param), Replacement(replacement), NameLoc(loc) {} + + SourceLocation getNameLoc() const { return NameLoc; } + SourceRange getSourceRange() const { return NameLoc; } + + Expr *getReplacement() const { return cast<Expr>(Replacement); } + + NonTypeTemplateParmDecl *getParameter() const { return Param; } + + static bool classof(const Stmt *s) { + return s->getStmtClass() == SubstNonTypeTemplateParmExprClass; + } + static bool classof(const SubstNonTypeTemplateParmExpr *) { + return true; + } + + // Iterators + child_range children() { return child_range(&Replacement, &Replacement+1); } +}; + /// \brief Represents a reference to a non-type template parameter pack that /// has been substituted with a non-template argument pack. /// @@ -2953,8 +3030,10 @@ class SubstNonTypeTemplateParmPackExpr : public Expr { /// \brief The location of the non-type template parameter pack reference. SourceLocation NameLoc; + friend class ASTReader; friend class ASTStmtReader; - friend class ASTStmtWriter; + explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty) + : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { } public: SubstNonTypeTemplateParmPackExpr(QualType T, @@ -2962,9 +3041,6 @@ public: SourceLocation NameLoc, const TemplateArgument &ArgPack); - SubstNonTypeTemplateParmPackExpr(EmptyShell Empty) - : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { } - /// \brief Retrieve the non-type template parameter pack being substituted. NonTypeTemplateParmDecl *getParameterPack() const { return Param; } @@ -2987,6 +3063,66 @@ public: // Iterators child_range children() { return child_range(); } }; + +/// \brief Represents a prvalue temporary that written into memory so that +/// a reference can bind to it. +/// +/// Prvalue expressions are materialized when they need to have an address +/// in memory for a reference to bind to. This happens when binding a +/// reference to the result of a conversion, e.g., +/// +/// \code +/// const int &r = 1.0; +/// \endcode +/// +/// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is +/// then materialized via a \c MaterializeTemporaryExpr, and the reference +/// 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. +class MaterializeTemporaryExpr : public Expr { + /// \brief The temporary-generating expression whose value will be + /// materialized. + Stmt *Temporary; + + friend class ASTStmtReader; + friend class ASTStmtWriter; + +public: + MaterializeTemporaryExpr(QualType T, Expr *Temporary, + bool BoundToLvalueReference) + : Expr(MaterializeTemporaryExprClass, T, + BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary, + Temporary->isTypeDependent(), Temporary->isValueDependent(), + Temporary->isInstantiationDependent(), + Temporary->containsUnexpandedParameterPack()), + Temporary(Temporary) { } + + 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); } + + /// \brief Determine whether this materialized temporary is bound to an + /// lvalue reference; otherwise, it's bound to an rvalue reference. + bool isBoundToLvalueReference() const { + return getValueKind() == VK_LValue; + } + + SourceRange getSourceRange() const { return Temporary->getSourceRange(); } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == MaterializeTemporaryExprClass; + } + static bool classof(const MaterializeTemporaryExpr *) { + return true; + } + + // Iterators + child_range children() { return child_range(&Temporary, &Temporary + 1); } +}; } // end namespace clang diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 8163923..49d4cfe 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -30,7 +30,7 @@ class ObjCStringLiteral : public Expr { public: ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, - false), + false, false), String(SL), AtLoc(L) {} explicit ObjCStringLiteral(EmptyShell Empty) : Expr(ObjCStringLiteralClass, Empty) {} @@ -67,6 +67,7 @@ public: : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, EncodedType->getType()->isDependentType(), EncodedType->getType()->isDependentType(), + EncodedType->getType()->isInstantiationDependentType(), EncodedType->getType()->containsUnexpandedParameterPack()), EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} @@ -106,7 +107,7 @@ public: ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, SourceLocation rp) : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, - false), + false, false), SelName(selInfo), AtLoc(at), RParenLoc(rp){} explicit ObjCSelectorExpr(EmptyShell Empty) : Expr(ObjCSelectorExprClass, Empty) {} @@ -146,7 +147,7 @@ public: ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, SourceLocation rp) : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, - false), + false, false), TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} explicit ObjCProtocolExpr(EmptyShell Empty) : Expr(ObjCProtocolExprClass, Empty) {} @@ -186,6 +187,7 @@ public: bool arrow = false, bool freeIvar = false) : Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary, /*TypeDependent=*/false, base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {} @@ -248,6 +250,7 @@ public: SourceLocation l, Expr *base) : Expr(ObjCPropertyRefExprClass, t, VK, OK, /*TypeDependent=*/false, base->isValueDependent(), + base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), PropertyOrGetter(PD, false), Setter(0), IdLoc(l), ReceiverLoc(), Receiver(base) { @@ -257,7 +260,7 @@ public: ExprValueKind VK, ExprObjectKind OK, SourceLocation l, SourceLocation sl, QualType st) : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, false, + /*TypeDependent=*/false, false, st->isInstantiationDependentType(), st->containsUnexpandedParameterPack()), PropertyOrGetter(PD, false), Setter(0), IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { @@ -267,7 +270,7 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, Expr *Base) : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, - Base->isValueDependent(), + Base->isValueDependent(), Base->isInstantiationDependent(), Base->containsUnexpandedParameterPack()), PropertyOrGetter(Getter, true), Setter(Setter), IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) { @@ -277,7 +280,7 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, SourceLocation SuperLoc, QualType SuperTy) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false), + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), PropertyOrGetter(Getter, true), Setter(Setter), IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { } @@ -286,7 +289,7 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false), + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), PropertyOrGetter(Getter, true), Setter(Setter), IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { } @@ -456,7 +459,11 @@ class ObjCMessageExpr : public Expr { /// /// When non-zero, we have a method declaration; otherwise, we just /// have a selector. - unsigned HasMethod : 8; + unsigned HasMethod : 1; + + /// \brief Whether this message send is a "delegate init call", + /// i.e. a call of an init method on self from within an init method. + unsigned IsDelegateInitCall : 1; /// \brief When the message expression is a send to 'super', this is /// the location of the 'super' keyword. @@ -476,7 +483,7 @@ class ObjCMessageExpr : public Expr { ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), - HasMethod(0), SelectorOrMethod(0) { } + HasMethod(0), IsDelegateInitCall(0), SelectorOrMethod(0) { } ObjCMessageExpr(QualType T, ExprValueKind VK, SourceLocation LBracLoc, @@ -807,6 +814,12 @@ public: getArgs()[Arg] = ArgExpr; } + /// isDelegateInitCall - Answers whether this message send has been + /// tagged as a "delegate init call", i.e. a call to a method in the + /// -init family on self from within an -init method implementation. + bool isDelegateInitCall() const { return IsDelegateInitCall; } + void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; } + SourceLocation getLeftLoc() const { return LBracLoc; } SourceLocation getRightLoc() const { return RBracLoc; } SourceLocation getSelectorLoc() const { return SelectorLoc; } @@ -860,6 +873,7 @@ public: ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, /*TypeDependent=*/false, base->isValueDependent(), + base->isInstantiationDependent(), /*ContainsUnexpandedParameterPack=*/false), Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} @@ -892,6 +906,123 @@ public: child_range children() { return child_range(&Base, &Base+1); } }; + +/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function +/// argument by indirect copy-restore in ARC. This is used to support +/// passing indirect arguments with the wrong lifetime, e.g. when +/// passing the address of a __strong local variable to an 'out' +/// parameter. This expression kind is only valid in an "argument" +/// position to some sort of call expression. +/// +/// The parameter must have type 'pointer to T', and the argument must +/// have type 'pointer to U', where T and U agree except possibly in +/// qualification. If the argument value is null, then a null pointer +/// is passed; otherwise it points to an object A, and: +/// 1. A temporary object B of type T is initialized, either by +/// zero-initialization (used when initializing an 'out' parameter) +/// or copy-initialization (used when initializing an 'inout' +/// parameter). +/// 2. The address of the temporary is passed to the function. +/// 3. If the call completes normally, A is move-assigned from B. +/// 4. Finally, A is destroyed immediately. +/// +/// Currently 'T' must be a retainable object lifetime and must be +/// __autoreleasing; this qualifier is ignored when initializing +/// the value. +class ObjCIndirectCopyRestoreExpr : public Expr { + Stmt *Operand; + + // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1; + + friend class ASTReader; + friend class ASTStmtReader; + + void setShouldCopy(bool shouldCopy) { + ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy; + } + + explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty) + : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { } + +public: + ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) + : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, + operand->isTypeDependent(), operand->isValueDependent(), + operand->isInstantiationDependent(), + operand->containsUnexpandedParameterPack()), + Operand(operand) { + setShouldCopy(shouldCopy); + } + + Expr *getSubExpr() { return cast<Expr>(Operand); } + const Expr *getSubExpr() const { return cast<Expr>(Operand); } + + /// shouldCopy - True if we should do the 'copy' part of the + /// copy-restore. If false, the temporary will be zero-initialized. + bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; } + + child_range children() { return child_range(&Operand, &Operand+1); } + + // Source locations are determined by the subexpression. + SourceRange getSourceRange() const { return Operand->getSourceRange(); } + SourceLocation getExprLoc() const { return getSubExpr()->getExprLoc(); } + + static bool classof(const Stmt *s) { + return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass; + } + static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; } +}; + +/// \brief An Objective-C "bridged" cast expression, which casts between +/// Objective-C pointers and C pointers, transferring ownership in the process. +/// +/// \code +/// NSString *str = (__bridge_transfer NSString *)CFCreateString(); +/// \endcode +class ObjCBridgedCastExpr : public ExplicitCastExpr { + SourceLocation LParenLoc; + SourceLocation BridgeKeywordLoc; + unsigned Kind : 2; + + friend class ASTStmtReader; + friend class ASTStmtWriter; + +public: + ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, + SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, + Expr *Operand) + : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue, + CK_BitCast, Operand, 0, TSInfo), + LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { } + + /// \brief Construct an empty Objective-C bridged cast. + explicit ObjCBridgedCastExpr(EmptyShell Shell) + : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { } + + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Determine which kind of bridge is being performed via this cast. + ObjCBridgeCastKind getBridgeKind() const { + return static_cast<ObjCBridgeCastKind>(Kind); + } + + /// \brief Retrieve the kind of bridge being performed as a string. + llvm::StringRef getBridgeKindName() const; + + /// \brief The location of the bridge keyword. + SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; } + + SourceRange getSourceRange() const { + return SourceRange(LParenLoc, getSubExpr()->getLocEnd()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCBridgedCastExprClass; + } + static bool classof(const ObjCBridgedCastExpr *) { return true; } + +}; + } // end namespace clang #endif diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index 846813a..ef1f161 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -32,6 +32,20 @@ class Selector; class Stmt; class TagDecl; +/// \brief Enumeration describing the result of loading information from +/// an external source. +enum ExternalLoadResult { + /// \brief Loading the external information has succeeded. + ELR_Success, + + /// \brief Loading the external information has failed. + ELR_Failure, + + /// \brief The external information has already been loaded, and therefore + /// no additional processing is required. + ELR_AlreadyLoaded +}; + /// \brief Abstract interface for external sources of AST nodes. /// /// External AST sources provide AST nodes constructed from some @@ -132,10 +146,10 @@ public: /// declaration kind is one we are looking for. If NULL, all declarations /// are returned. /// - /// \return true if an error occurred + /// \return an indication of whether the load succeeded or failed. /// /// The default implementation of this method is a no-op. - virtual bool FindExternalLexicalDecls(const DeclContext *DC, + virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl<Decl*> &Result); @@ -143,14 +157,14 @@ public: /// DeclContext. /// /// \return true if an error occurred - bool FindExternalLexicalDecls(const DeclContext *DC, + ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, llvm::SmallVectorImpl<Decl*> &Result) { return FindExternalLexicalDecls(DC, 0, Result); } template <typename DeclTy> - bool FindExternalLexicalDeclsBy(const DeclContext *DC, - llvm::SmallVectorImpl<Decl*> &Result) { + ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC, + llvm::SmallVectorImpl<Decl*> &Result) { return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result); } diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h new file mode 100644 index 0000000..c43e44c --- /dev/null +++ b/include/clang/AST/GlobalDecl.h @@ -0,0 +1,124 @@ +//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor +// together with its type. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_GLOBALDECL_H +#define LLVM_CLANG_AST_GLOBALDECL_H + +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/Basic/ABI.h" + +namespace clang { + +/// GlobalDecl - represents a global declaration. This can either be a +/// CXXConstructorDecl and the constructor type (Base, Complete). +/// a CXXDestructorDecl and the destructor type (Base, Complete) or +/// a VarDecl, a FunctionDecl or a BlockDecl. +class GlobalDecl { + llvm::PointerIntPair<const Decl*, 2> Value; + + void Init(const Decl *D) { + assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); + assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!"); + + Value.setPointer(D); + } + +public: + GlobalDecl() {} + + GlobalDecl(const VarDecl *D) { Init(D);} + GlobalDecl(const FunctionDecl *D) { Init(D); } + GlobalDecl(const BlockDecl *D) { Init(D); } + GlobalDecl(const ObjCMethodDecl *D) { Init(D); } + + GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) + : Value(D, Type) {} + GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) + : Value(D, Type) {} + + GlobalDecl getCanonicalDecl() const { + GlobalDecl CanonGD; + CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl()); + CanonGD.Value.setInt(Value.getInt()); + + return CanonGD; + } + + const Decl *getDecl() const { return Value.getPointer(); } + + CXXCtorType getCtorType() const { + assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); + return static_cast<CXXCtorType>(Value.getInt()); + } + + CXXDtorType getDtorType() const { + assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!"); + return static_cast<CXXDtorType>(Value.getInt()); + } + + friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { + return LHS.Value == RHS.Value; + } + + void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } + + static GlobalDecl getFromOpaquePtr(void *P) { + GlobalDecl GD; + GD.Value.setFromOpaqueValue(P); + return GD; + } + + GlobalDecl getWithDecl(const Decl *D) { + GlobalDecl Result(*this); + Result.Value.setPointer(D); + return Result; + } +}; + +} // end namespace clang + +namespace llvm { + template<class> struct DenseMapInfo; + + template<> struct DenseMapInfo<clang::GlobalDecl> { + static inline clang::GlobalDecl getEmptyKey() { + return clang::GlobalDecl(); + } + + static inline clang::GlobalDecl getTombstoneKey() { + return clang::GlobalDecl:: + getFromOpaquePtr(reinterpret_cast<void*>(-1)); + } + + static unsigned getHashValue(clang::GlobalDecl GD) { + return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr()); + } + + static bool isEqual(clang::GlobalDecl LHS, + clang::GlobalDecl RHS) { + return LHS == RHS; + } + + }; + + // GlobalDecl isn't *technically* a POD type. However, its copy constructor, + // copy assignment operator, and destructor are all trivial. + template <> + struct isPodLike<clang::GlobalDecl> { + static const bool value = true; + }; +} // end namespace llvm + +#endif diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index c21c76b..018041f 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -186,6 +186,10 @@ public: /// type or not. bool isDependent() const; + /// \brief Whether this nested name specifier involves a template + /// parameter. + bool isInstantiationDependent() const; + /// \brief Whether this nested-name-specifier contains an unexpanded /// parameter pack (for C++0x variadic templates). bool containsUnexpandedParameterPack() const; @@ -435,6 +439,14 @@ public: /// copied. NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; + /// \brief Retrieve a nested-name-specifier with location + /// information based on the information in this builder. This loc + /// will contain references to the builder's internal data and may + /// be invalidated by any change to the builder. + NestedNameSpecifierLoc getTemporary() const { + return NestedNameSpecifierLoc(Representation, Buffer); + } + /// \brief Clear out this builder, and prepare it to build another /// nested-name-specifier with source-location information. void Clear() { diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h index 35c72c4..92ff604 100644 --- a/include/clang/AST/OperationKinds.h +++ b/include/clang/AST/OperationKinds.h @@ -245,7 +245,22 @@ enum CastKind { /// \brief Converts from an integral complex to a floating complex. /// _Complex unsigned -> _Complex float - CK_IntegralComplexToFloatingComplex + CK_IntegralComplexToFloatingComplex, + + /// \brief Produces a retainable object pointer so that it may be + /// consumed, e.g. by being passed to a consuming parameter. Calls + /// objc_retain. + CK_ObjCProduceObject, + + /// \brief Consumes a retainable object pointer that has just been + /// produced, e.g. as the return value of a retaining call. Enters + /// a cleanup to call objc_release at some indefinite time. + CK_ObjCConsumeObject, + + /// \brief Reclaim a retainable object pointer object that may have + /// been produced and autoreleased as part of a function return + /// sequence. + CK_ObjCReclaimReturnedObject }; #define CK_Invalid ((CastKind) -1) @@ -284,6 +299,19 @@ enum UnaryOperatorKind { UO_Extension // __extension__ marker. }; +/// \brief The kind of bridging performed by the Objective-C bridge cast. +enum ObjCBridgeCastKind { + /// \brief Bridging via __bridge, which does nothing but reinterpret + /// the bits. + OBC_Bridge, + /// \brief Bridging via __bridge_transfer, which transfers ownership of an + /// Objective-C pointer into ARC. + OBC_BridgeTransfer, + /// \brief Bridging via __bridge_retain, which makes an ARC object available + /// as a +1 C pointer. + OBC_BridgeRetained +}; + } #endif diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h index 9ea5a09..22c1e72 100644 --- a/include/clang/AST/ParentMap.h +++ b/include/clang/AST/ParentMap.h @@ -32,6 +32,7 @@ public: Stmt *getParent(Stmt*) const; Stmt *getParentIgnoreParens(Stmt *) const; Stmt *getParentIgnoreParenCasts(Stmt *) const; + Stmt *getOuterParenParent(Stmt *) const; const Stmt *getParent(const Stmt* S) const { return getParent(const_cast<Stmt*>(S)); diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index cf5fadb..fc8ac36 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -41,7 +41,7 @@ struct PrintingPolicy { SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false), SuppressInitializers(false), Dump(false), ConstantArraySizeAsWritten(false), - AnonymousTagLocations(true) { } + AnonymousTagLocations(true), SuppressStrongLifetime(false) { } /// \brief The number of spaces to use to indent each line. unsigned Indentation : 8; @@ -129,6 +129,10 @@ struct PrintingPolicy { /// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just /// prints "<anonymous>" for the name. bool AnonymousTagLocations : 1; + + /// \brief When true, suppress printing of the __strong lifetime qualifier in + /// ARC. + unsigned SuppressStrongLifetime : 1; }; } // end namespace clang diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index a8f182a..85c5c08 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1721,6 +1721,7 @@ DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { }) DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { }) DEF_TRAVERSE_STMT(ObjCAtTryStmt, { }) DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { }) +DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { }) DEF_TRAVERSE_STMT(CXXForRangeStmt, { }) DEF_TRAVERSE_STMT(ReturnStmt, { }) DEF_TRAVERSE_STMT(SwitchStmt, { }) @@ -1933,6 +1934,10 @@ DEF_TRAVERSE_STMT(ObjCMessageExpr, { }) DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { }) DEF_TRAVERSE_STMT(ObjCProtocolExpr, { }) DEF_TRAVERSE_STMT(ObjCSelectorExpr, { }) +DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { }) +DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, { + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); +}) DEF_TRAVERSE_STMT(ParenExpr, { }) DEF_TRAVERSE_STMT(ParenListExpr, { }) DEF_TRAVERSE_STMT(PredefinedExpr, { }) @@ -1973,6 +1978,8 @@ DEF_TRAVERSE_STMT(CXXNoexceptExpr, { }) DEF_TRAVERSE_STMT(PackExpansionExpr, { }) DEF_TRAVERSE_STMT(SizeOfPackExpr, { }) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { }) +DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { }) +DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { }) // These literals (all of them) do not need any action. DEF_TRAVERSE_STMT(IntegerLiteral, { }) diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 695fb04..bf5f383 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -154,9 +154,10 @@ protected: unsigned ObjectKind : 2; unsigned TypeDependent : 1; unsigned ValueDependent : 1; + unsigned InstantiationDependent : 1; unsigned ContainsUnexpandedParameterPack : 1; }; - enum { NumExprBits = 15 }; + enum { NumExprBits = 16 }; class DeclRefExprBitfields { friend class DeclRefExpr; @@ -183,6 +184,13 @@ protected: unsigned NumPreArgs : 1; }; + class ObjCIndirectCopyRestoreExprBitfields { + friend class ObjCIndirectCopyRestoreExpr; + unsigned : NumExprBits; + + unsigned ShouldCopy : 1; + }; + union { // FIXME: this is wasteful on 64-bit platforms. void *Aligner; @@ -193,6 +201,7 @@ protected: DeclRefExprBitfields DeclRefExprBits; CastExprBitfields CastExprBits; CallExprBitfields CallExprBits; + ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits; }; friend class ASTStmtReader; @@ -284,6 +293,10 @@ public: /// works on systems with GraphViz (Mac OS X) or dot+gv installed. void viewAST() const; + /// Skip past any implicit AST nodes which might surround this + /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes. + Stmt *IgnoreImplicit(); + // Implement isa<T> support. static bool classof(const Stmt *) { return true; } @@ -327,7 +340,7 @@ public: /// declaration pointers) or the exact representation of the statement as /// written in the source. void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, - bool Canonical); + bool Canonical) const; }; /// DeclStmt - Adaptor class for mixing declarations with statements and @@ -1458,6 +1471,10 @@ class SEHExceptStmt : public Stmt { Expr *FilterExpr, Stmt *Block); + friend class ASTReader; + friend class ASTStmtReader; + explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { } + public: static SEHExceptStmt* Create(ASTContext &C, SourceLocation ExceptLoc, @@ -1492,6 +1509,10 @@ class SEHFinallyStmt : public Stmt { SEHFinallyStmt(SourceLocation Loc, Stmt *Block); + friend class ASTReader; + friend class ASTStmtReader; + explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { } + public: static SEHFinallyStmt* Create(ASTContext &C, SourceLocation FinallyLoc, @@ -1530,6 +1551,10 @@ class SEHTryStmt : public Stmt { Stmt *TryBlock, Stmt *Handler); + friend class ASTReader; + friend class ASTStmtReader; + explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { } + public: static SEHTryStmt* Create(ASTContext &C, bool isCXXTry, diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h index 1800a71..d996fc5 100644 --- a/include/clang/AST/StmtObjC.h +++ b/include/clang/AST/StmtObjC.h @@ -342,6 +342,39 @@ public: child_range children() { return child_range(&Throw, &Throw+1); } }; +/// ObjCAutoreleasePoolStmt - This represent objective-c's +/// @autoreleasepool Statement +class ObjCAutoreleasePoolStmt : public Stmt { + Stmt *SubStmt; + SourceLocation AtLoc; +public: + ObjCAutoreleasePoolStmt(SourceLocation atLoc, + Stmt *subStmt) + : Stmt(ObjCAutoreleasePoolStmtClass), + SubStmt(subStmt), AtLoc(atLoc) {} + + explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) : + Stmt(ObjCAutoreleasePoolStmtClass, Empty) { } + + const Stmt *getSubStmt() const { return SubStmt; } + Stmt *getSubStmt() { return SubStmt; } + void setSubStmt(Stmt *S) { SubStmt = S; } + + SourceRange getSourceRange() const { + return SourceRange(AtLoc, SubStmt->getLocEnd()); + } + + SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCAutoreleasePoolStmtClass; + } + static bool classof(const ObjCAutoreleasePoolStmt *) { return true; } + + child_range children() { return child_range(&SubStmt, &SubStmt + 1); } +}; + } // end namespace clang #endif diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 821b4fc..1c693e0 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -235,9 +235,14 @@ public: bool isNull() const { return Kind == Null; } /// \brief Whether this template argument is dependent on a template - /// parameter. + /// parameter such that its result can change from one instantiation to + /// another. bool isDependent() const; + /// \brief Whether this template argument is dependent on a template + /// parameter. + bool isInstantiationDependent() const; + /// \brief Whether this template argument contains an unexpanded /// parameter pack. bool containsUnexpandedParameterPack() const; diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 1721973..a180f58 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -33,6 +33,7 @@ class OverloadedTemplateStorage; struct PrintingPolicy; class QualifiedTemplateName; class NamedDecl; +class SubstTemplateTemplateParmStorage; class SubstTemplateTemplateParmPackStorage; class TemplateArgument; class TemplateDecl; @@ -42,38 +43,49 @@ class TemplateTemplateParmDecl; /// template names or an already-substituted template template parameter pack. class UncommonTemplateNameStorage { protected: + enum Kind { + Overloaded, + SubstTemplateTemplateParm, + SubstTemplateTemplateParmPack + }; + union { struct { - /// \brief If true, this is an OverloadedTemplateStorage instance; - /// otherwise, it's a SubstTemplateTemplateParmPackStorage instance. - unsigned IsOverloadedStorage : 1; + /// \brief A Kind. + unsigned Kind : 2; /// \brief The number of stored templates or template arguments, /// depending on which subclass we have. - unsigned Size : 31; + unsigned Size : 30; } Bits; void *PointerAlignment; }; - UncommonTemplateNameStorage(unsigned Size, bool OverloadedStorage) { - Bits.IsOverloadedStorage = OverloadedStorage; - Bits.Size = Size; + UncommonTemplateNameStorage(Kind kind, unsigned size) { + Bits.Kind = kind; + Bits.Size = size; } public: unsigned size() const { return Bits.Size; } OverloadedTemplateStorage *getAsOverloadedStorage() { - return Bits.IsOverloadedStorage + return Bits.Kind == Overloaded ? reinterpret_cast<OverloadedTemplateStorage *>(this) : 0; } + SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() { + return Bits.Kind == SubstTemplateTemplateParm + ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this) + : 0; + } + SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() { - return Bits.IsOverloadedStorage - ? 0 - : reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this) ; + return Bits.Kind == SubstTemplateTemplateParmPack + ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this) + : 0; } }; @@ -82,8 +94,8 @@ public: class OverloadedTemplateStorage : public UncommonTemplateNameStorage { friend class ASTContext; - OverloadedTemplateStorage(unsigned Size) - : UncommonTemplateNameStorage(Size, true) { } + OverloadedTemplateStorage(unsigned size) + : UncommonTemplateNameStorage(Overloaded, size) { } NamedDecl **getStorage() { return reinterpret_cast<NamedDecl **>(this + 1); @@ -98,8 +110,7 @@ public: iterator begin() const { return getStorage(); } iterator end() const { return getStorage() + size(); } }; - - + /// \brief A structure for storing an already-substituted template template /// parameter pack. /// @@ -109,16 +120,14 @@ public: class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage, public llvm::FoldingSetNode { - ASTContext &Context; TemplateTemplateParmDecl *Parameter; const TemplateArgument *Arguments; public: - SubstTemplateTemplateParmPackStorage(ASTContext &Context, - TemplateTemplateParmDecl *Parameter, + SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter, unsigned Size, const TemplateArgument *Arguments) - : UncommonTemplateNameStorage(Size, false), Context(Context), + : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size), Parameter(Parameter), Arguments(Arguments) { } /// \brief Retrieve the template template parameter pack being substituted. @@ -130,9 +139,10 @@ public: /// parameter was substituted. TemplateArgument getArgumentPack() const; - void Profile(llvm::FoldingSetNodeID &ID); + void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context); - static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context, + static void Profile(llvm::FoldingSetNodeID &ID, + ASTContext &Context, TemplateTemplateParmDecl *Parameter, const TemplateArgument &ArgPack); }; @@ -189,6 +199,9 @@ public: /// \brief A dependent template name that has not been resolved to a /// template (or set of templates). DependentTemplate, + /// \brief A template template parameter that has been substituted + /// for some other template name. + SubstTemplateTemplateParm, /// \brief A template template parameter pack that has been substituted for /// a template template argument pack, but has not yet been expanded into /// individual arguments. @@ -199,6 +212,7 @@ public: explicit TemplateName(TemplateDecl *Template) : Storage(Template) { } explicit TemplateName(OverloadedTemplateStorage *Storage) : Storage(Storage) { } + explicit TemplateName(SubstTemplateTemplateParmStorage *Storage); explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage) : Storage(Storage) { } explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { } @@ -234,6 +248,19 @@ public: return 0; } + /// \brief Retrieve the substituted template template parameter, if + /// known. + /// + /// \returns The storage for the substituted template template parameter, + /// if known. Otherwise, returns NULL. + SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const { + if (UncommonTemplateNameStorage *uncommon = + Storage.dyn_cast<UncommonTemplateNameStorage *>()) + return uncommon->getAsSubstTemplateTemplateParm(); + + return 0; + } + /// \brief Retrieve the substituted template template parameter pack, if /// known. /// @@ -260,9 +287,15 @@ public: return Storage.dyn_cast<DependentTemplateName *>(); } + TemplateName getUnderlying() const; + /// \brief Determines whether this is a dependent template name. bool isDependent() const; + /// \brief Determines whether this is a template name that somehow + /// depends on a template parameter. + bool isInstantiationDependent() const; + /// \brief Determines whether this template name contains an /// unexpanded parameter pack (for C++0x variadic templates). bool containsUnexpandedParameterPack() const; @@ -300,6 +333,41 @@ public: const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, TemplateName N); +/// \brief A structure for storing the information associated with a +/// substituted template template parameter. +class SubstTemplateTemplateParmStorage + : public UncommonTemplateNameStorage, public llvm::FoldingSetNode { + friend class ASTContext; + + TemplateTemplateParmDecl *Parameter; + TemplateName Replacement; + + SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter, + TemplateName replacement) + : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0), + Parameter(parameter), Replacement(replacement) {} + +public: + TemplateTemplateParmDecl *getParameter() const { return Parameter; } + TemplateName getReplacement() const { return Replacement; } + + void Profile(llvm::FoldingSetNodeID &ID); + + static void Profile(llvm::FoldingSetNodeID &ID, + TemplateTemplateParmDecl *parameter, + TemplateName replacement); +}; + +inline TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage) + : Storage(Storage) { } + +inline TemplateName TemplateName::getUnderlying() const { + if (SubstTemplateTemplateParmStorage *subst + = getAsSubstTemplateTemplateParm()) + return subst->getReplacement().getUnderlying(); + return *this; +} + /// \brief Represents a template name that was expressed as a /// qualified name. /// diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 7763383..ef0dbda 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -126,6 +126,28 @@ public: Strong }; + enum ObjCLifetime { + /// There is no lifetime qualification on this type. + OCL_None, + + /// This object can be modified without requiring retains or + /// releases. + OCL_ExplicitNone, + + /// Assigning into this object requires the old value to be + /// released and the new value to be retained. The timing of the + /// release of the old value is inexact: it may be moved to + /// immediately after the last known point where the value is + /// live. + OCL_Strong, + + /// Reading or writing from this object requires a barrier call. + OCL_Weak, + + /// Assigning into this object requires a lifetime extension. + OCL_Autoreleasing + }; + enum { /// The maximum supported address space number. /// 24 bits should be enough for anyone. @@ -218,7 +240,37 @@ public: qs.removeObjCGCAttr(); return qs; } + Qualifiers withoutObjCGLifetime() const { + Qualifiers qs = *this; + qs.removeObjCLifetime(); + return qs; + } + + bool hasObjCLifetime() const { return Mask & LifetimeMask; } + ObjCLifetime getObjCLifetime() const { + return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift); + } + void setObjCLifetime(ObjCLifetime type) { + Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift); + } + void removeObjCLifetime() { setObjCLifetime(OCL_None); } + void addObjCLifetime(ObjCLifetime type) { + assert(type); + setObjCLifetime(type); + } + + /// True if the lifetime is neither None or ExplicitNone. + bool hasNonTrivialObjCLifetime() const { + ObjCLifetime lifetime = getObjCLifetime(); + return (lifetime > OCL_ExplicitNone); + } + /// True if the lifetime is either strong or weak. + bool hasStrongOrWeakObjCLifetime() const { + ObjCLifetime lifetime = getObjCLifetime(); + return (lifetime == OCL_Strong || lifetime == OCL_Weak); + } + bool hasAddressSpace() const { return Mask & AddressSpaceMask; } unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; } void setAddressSpace(unsigned space) { @@ -277,6 +329,8 @@ public: addAddressSpace(Q.getAddressSpace()); if (Q.hasObjCGCAttr()) addObjCGCAttr(Q.getObjCGCAttr()); + if (Q.hasObjCLifetime()) + addObjCLifetime(Q.getObjCLifetime()); } } @@ -287,6 +341,8 @@ public: !hasAddressSpace() || !qs.hasAddressSpace()); assert(getObjCGCAttr() == qs.getObjCGCAttr() || !hasObjCGCAttr() || !qs.hasObjCGCAttr()); + assert(getObjCLifetime() == qs.getObjCLifetime() || + !hasObjCLifetime() || !qs.hasObjCLifetime()); Mask |= qs.Mask; } @@ -301,10 +357,30 @@ public: // changed. (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() || !other.hasObjCGCAttr()) && + // ObjC lifetime qualifiers must match exactly. + getObjCLifetime() == other.getObjCLifetime() && // CVR qualifiers may subset. (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)); } + /// \brief Determines if these qualifiers compatibly include another set of + /// qualifiers from the narrow perspective of Objective-C ARC lifetime. + /// + /// One set of Objective-C lifetime qualifiers compatibly includes the other + /// if the lifetime qualifiers match, or if both are non-__weak and the + /// including set also contains the 'const' qualifier. + bool compatiblyIncludesObjCLifetime(Qualifiers other) const { + if (getObjCLifetime() == other.getObjCLifetime()) + return true; + + if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak) + return false; + + return hasConst(); + } + + bool isSupersetOf(Qualifiers Other) const; + /// \brief Determine whether this set of qualifiers is a strict superset of /// another set of qualifiers, not considering qualifier compatibility. bool isStrictSupersetOf(Qualifiers Other) const; @@ -351,14 +427,16 @@ public: private: - // bits: |0 1 2|3 .. 4|5 .. 31| - // |C R V|GCAttr|AddrSpace| + // bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31| + // |C R V|GCAttr|Lifetime|AddressSpace| uint32_t Mask; static const uint32_t GCAttrMask = 0x18; static const uint32_t GCAttrShift = 3; - static const uint32_t AddressSpaceMask = ~(CVRMask | GCAttrMask); - static const uint32_t AddressSpaceShift = 5; + static const uint32_t LifetimeMask = 0xE0; + static const uint32_t LifetimeShift = 5; + static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask); + static const uint32_t AddressSpaceShift = 8; }; /// CallingConv - Specifies the calling convention that a function uses. @@ -527,6 +605,23 @@ public: return QualType::isConstant(*this, Ctx); } + /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). + bool isPODType(ASTContext &Context) const; + + /// isCXX11PODType() - Return true if this is a POD type according to the + /// more relaxed rules of the C++11 standard, regardless of the current + /// compilation's language. + /// (C++0x [basic.types]p9) + bool isCXX11PODType(ASTContext &Context) const; + + /// isTrivialType - Return true if this is a trivial type + /// (C++0x [basic.types]p9) + bool isTrivialType(ASTContext &Context) const; + + /// isTriviallyCopyableType - Return true if this is a trivially + /// copyable type (C++0x [basic.types]p9) + bool isTriviallyCopyableType(ASTContext &Context) const; + // Don't promise in the API that anything besides 'const' can be // easily added. @@ -546,6 +641,10 @@ public: return withFastQualifiers(Qualifiers::Volatile); } + QualType withCVRQualifiers(unsigned CVR) const { + return withFastQualifiers(CVR); + } + void addFastQualifiers(unsigned TQs) { assert(!(TQs & ~Qualifiers::FastMask) && "non-fast qualifier bits set in mask!"); @@ -658,6 +757,13 @@ public: return getSplitDesugaredType(*this); } + /// \brief Return the specified type with one level of "sugar" removed from + /// the type. + /// + /// This routine takes off the first typedef, typeof, etc. If the outer level + /// of the type is already concrete, it returns it unmodified. + QualType getSingleStepDesugaredType(const ASTContext &Context) const; + /// IgnoreParens - Returns the specified type after dropping any /// outer-level parentheses. QualType IgnoreParens() const { @@ -709,7 +815,7 @@ public: /// getAddressSpace - Return the address space of this type. inline unsigned getAddressSpace() const; - /// GCAttrTypesAttr - Returns gc attribute of this type. + /// getObjCGCAttr - Returns gc attribute of this type. inline Qualifiers::GC getObjCGCAttr() const; /// isObjCGCWeak true when Type is objc's weak. @@ -722,9 +828,24 @@ public: return getObjCGCAttr() == Qualifiers::Strong; } + /// getObjCLifetime - Returns lifetime attribute of this type. + Qualifiers::ObjCLifetime getObjCLifetime() const { + return getQualifiers().getObjCLifetime(); + } + + bool hasNonTrivialObjCLifetime() const { + return getQualifiers().hasNonTrivialObjCLifetime(); + } + + bool hasStrongOrWeakObjCLifetime() const { + return getQualifiers().hasStrongOrWeakObjCLifetime(); + } + enum DestructionKind { DK_none, - DK_cxx_destructor + DK_cxx_destructor, + DK_objc_strong_lifetime, + DK_objc_weak_lifetime }; /// isDestructedType - nonzero if objects of this type require @@ -735,6 +856,21 @@ public: return isDestructedTypeImpl(*this); } + /// \brief Determine whether expressions of the given type are forbidden + /// from being lvalues in C. + /// + /// The expression types that are forbidden to be lvalues are: + /// - 'void', but not qualified void + /// - function types + /// + /// The exact rule here is C99 6.3.2.1: + /// An lvalue is an expression with an object type or an incomplete + /// type other than void. + bool isCForbiddenLValueType() const; + + /// \brief Determine whether this type has trivial copy-assignment semantics. + bool hasTrivialCopyAssignment(ASTContext &Context) const; + private: // These methods are implemented in a separate translation unit; // "static"-ize them to avoid creating temporary QualTypes in the @@ -849,6 +985,11 @@ public: bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); } Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); } + bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); } + Qualifiers::ObjCLifetime getObjCLifetime() const { + return Quals.getObjCLifetime(); + } + bool hasAddressSpace() const { return Quals.hasAddressSpace(); } unsigned getAddressSpace() const { return Quals.getAddressSpace(); } @@ -931,6 +1072,10 @@ private: /// subclasses can pack their bitfields into the same word. unsigned Dependent : 1; + /// \brief Whether this type somehow involves a template parameter, even + /// if the resolution of the type does not depend on a template parameter. + unsigned InstantiationDependent : 1; + /// \brief Whether this type is a variably-modified type (C99 6.7.5). unsigned VariablyModified : 1; @@ -968,7 +1113,7 @@ private: return CachedLocalOrUnnamed; } }; - enum { NumTypeBits = 17 }; + enum { NumTypeBits = 18 }; protected: // These classes allow subclasses to somewhat cleanly pack bitfields @@ -1111,12 +1256,14 @@ private: protected: // silence VC++ warning C4355: 'this' : used in base member initializer list Type *this_() { return this; } - Type(TypeClass tc, QualType canon, bool Dependent, bool VariablyModified, + Type(TypeClass tc, QualType canon, bool Dependent, + bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack) : ExtQualsTypeCommonBase(this, canon.isNull() ? QualType(this_(), 0) : canon) { TypeBits.TC = tc; TypeBits.Dependent = Dependent; + TypeBits.InstantiationDependent = Dependent || InstantiationDependent; TypeBits.VariablyModified = VariablyModified; TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; TypeBits.CacheValidAndVisibility = 0; @@ -1126,8 +1273,15 @@ protected: } friend class ASTContext; - void setDependent(bool D = true) { TypeBits.Dependent = D; } - void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; } + void setDependent(bool D = true) { + TypeBits.Dependent = D; + if (D) + TypeBits.InstantiationDependent = true; + } + void setInstantiationDependent(bool D = true) { + TypeBits.InstantiationDependent = D; } + void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; + } void setContainsUnexpandedParameterPack(bool PP = true) { TypeBits.ContainsUnexpandedParameterPack = PP; } @@ -1186,31 +1340,14 @@ public: return !isReferenceType() && !isFunctionType() && !isVoidType(); } - /// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10). - bool isPODType() const; - /// isLiteralType - Return true if this is a literal type /// (C++0x [basic.types]p10) bool isLiteralType() const; - /// isTrivialType - Return true if this is a trivial type - /// (C++0x [basic.types]p9) - bool isTrivialType() const; - - /// isTriviallyCopyableType - Return true if this is a trivially copyable type - /// (C++0x [basic.types]p9 - bool isTriviallyCopyableType() const; - /// \brief Test if this type is a standard-layout type. /// (C++0x [basic.type]p9) bool isStandardLayoutType() const; - /// isCXX11PODType() - Return true if this is a POD type according to the - /// more relaxed rules of the C++11 standard, regardless of the current - /// compilation's language. - /// (C++0x [basic.types]p9) - bool isCXX11PODType() const; - /// Helper methods to distinguish type categories. All type predicates /// operate on the canonical type, ignoring typedefs and qualifiers. @@ -1290,7 +1427,11 @@ public: bool isComplexIntegerType() const; // GCC _Complex integer type. bool isVectorType() const; // GCC vector type. bool isExtVectorType() const; // Extended vector type. - bool isObjCObjectPointerType() const; // Pointer to *any* ObjC object. + bool isObjCObjectPointerType() const; // pointer to ObjC object + bool isObjCRetainableType() const; // ObjC object or block pointer + bool isObjCLifetimeType() const; // (array of)* retainable type + bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type + bool isObjCNSObjectType() const; // __attribute__((NSObject)) // FIXME: change this to 'raw' interface type, so we can used 'interface' type // for the common case. bool isObjCObjectType() const; // NSString or typeof(*(id)0) @@ -1302,9 +1443,19 @@ public: bool isObjCClassType() const; // Class bool isObjCSelType() const; // Class bool isObjCBuiltinType() const; // 'id' or 'Class' + bool isObjCARCBridgableType() const; + bool isCARCBridgableType() const; bool isTemplateTypeParmType() const; // C++ template type parameter bool isNullPtrType() const; // C++0x nullptr_t + /// Determines if this type, which must satisfy + /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather + /// than implicitly __strong. + bool isObjCARCImplicitlyUnretainedType() const; + + /// Return the implicit lifetime for this type, which must not be dependent. + Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; + enum ScalarTypeKind { STK_Pointer, STK_MemberPointer, @@ -1322,6 +1473,14 @@ public: /// (C++ [temp.dep.type]). bool isDependentType() const { return TypeBits.Dependent; } + /// \brief Determine whether this type is an instantiation-dependent type, + /// meaning that the type involves a template parameter (even if the + /// definition does not actually depend on the type substituted for that + /// template parameter). + bool isInstantiationDependentType() const { + return TypeBits.InstantiationDependent; + } + /// \brief Whether this type is a variably-modified type (C99 6.7.5). bool isVariablyModifiedType() const { return TypeBits.VariablyModified; } @@ -1336,6 +1495,8 @@ public: /// \brief Determine wither this type is a C++ elaborated-type-specifier. bool isElaboratedTypeSpecifier() const; + + bool canDecayToPointerType() const; /// hasPointerRepresentation - Whether this type is represented /// natively as a pointer; this includes pointers, references, block @@ -1480,6 +1641,7 @@ public: } CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h void dump() const; + static bool classof(const Type *) { return true; } friend class ASTReader; @@ -1586,6 +1748,7 @@ public: public: BuiltinType(Kind K) : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), + /*InstantiationDependent=*/(K == Dependent), /*VariablyModified=*/false, /*Unexpanded paramter pack=*/false) { BuiltinTypeBits.Kind = K; @@ -1631,6 +1794,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode { QualType ElementType; ComplexType(QualType Element, QualType CanonicalPtr) : Type(Complex, CanonicalPtr, Element->isDependentType(), + Element->isInstantiationDependentType(), Element->isVariablyModifiedType(), Element->containsUnexpandedParameterPack()), ElementType(Element) { @@ -1661,6 +1825,7 @@ class ParenType : public Type, public llvm::FoldingSetNode { ParenType(QualType InnerType, QualType CanonType) : Type(Paren, CanonType, InnerType->isDependentType(), + InnerType->isInstantiationDependentType(), InnerType->isVariablyModifiedType(), InnerType->containsUnexpandedParameterPack()), Inner(InnerType) { @@ -1692,6 +1857,7 @@ class PointerType : public Type, public llvm::FoldingSetNode { PointerType(QualType Pointee, QualType CanonicalPtr) : Type(Pointer, CanonicalPtr, Pointee->isDependentType(), + Pointee->isInstantiationDependentType(), Pointee->isVariablyModifiedType(), Pointee->containsUnexpandedParameterPack()), PointeeType(Pointee) { @@ -1724,6 +1890,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; // Block is some kind of pointer type BlockPointerType(QualType Pointee, QualType CanonicalCls) : Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), + Pointee->isInstantiationDependentType(), Pointee->isVariablyModifiedType(), Pointee->containsUnexpandedParameterPack()), PointeeType(Pointee) { @@ -1760,6 +1927,7 @@ protected: ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, bool SpelledAsLValue) : Type(tc, CanonicalRef, Referencee->isDependentType(), + Referencee->isInstantiationDependentType(), Referencee->isVariablyModifiedType(), Referencee->containsUnexpandedParameterPack()), PointeeType(Referencee) @@ -1844,6 +2012,8 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode { MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : Type(MemberPointer, CanonicalPtr, Cls->isDependentType() || Pointee->isDependentType(), + (Cls->isInstantiationDependentType() || + Pointee->isInstantiationDependentType()), Pointee->isVariablyModifiedType(), (Cls->containsUnexpandedParameterPack() || Pointee->containsUnexpandedParameterPack())), @@ -1911,6 +2081,7 @@ protected: ArraySizeModifier sm, unsigned tq, bool ContainsUnexpandedParameterPack) : Type(tc, can, et->isDependentType() || tc == DependentSizedArray, + et->isInstantiationDependentType() || tc == DependentSizedArray, (tc == VariableArray || et->isVariablyModifiedType()), ContainsUnexpandedParameterPack), ElementType(et) { @@ -2344,28 +2515,32 @@ class FunctionType : public Type { // you'll need to adjust both the Bits field below and // Type::FunctionTypeBitfields. - // | CC |noreturn|hasregparm|regparm - // |0 .. 2| 3 | 4 |5 .. 7 + // | CC |noreturn|produces|regparm| + // |0 .. 2| 3 | 4 | 5 .. 7| + // + // regparm is either 0 (no regparm attribute) or the regparm value+1. enum { CallConvMask = 0x7 }; enum { NoReturnMask = 0x8 }; - enum { HasRegParmMask = 0x10 }; - enum { RegParmMask = ~(CallConvMask | NoReturnMask), - RegParmOffset = 5 }; + enum { ProducesResultMask = 0x10 }; + enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask), + RegParmOffset = 5 }; // Assumed to be the last field - unsigned char Bits; + uint16_t Bits; - ExtInfo(unsigned Bits) : Bits(static_cast<unsigned char>(Bits)) {} + ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {} friend class FunctionType; public: // Constructor with no defaults. Use this when you know that you // have all the elements (when reading an AST file for example). - ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc) { + ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, + bool producesResult) { + assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); Bits = ((unsigned) cc) | (noReturn ? NoReturnMask : 0) | - (hasRegParm ? HasRegParmMask : 0) | - (regParm << RegParmOffset); + (producesResult ? ProducesResultMask : 0) | + (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0); } // Constructor with all defaults. Use when for example creating a @@ -2373,8 +2548,14 @@ class FunctionType : public Type { ExtInfo() : Bits(0) {} bool getNoReturn() const { return Bits & NoReturnMask; } - bool getHasRegParm() const { return Bits & HasRegParmMask; } - unsigned getRegParm() const { return Bits >> RegParmOffset; } + bool getProducesResult() const { return Bits & ProducesResultMask; } + bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } + unsigned getRegParm() const { + unsigned RegParm = Bits >> RegParmOffset; + if (RegParm > 0) + --RegParm; + return RegParm; + } CallingConv getCC() const { return CallingConv(Bits & CallConvMask); } bool operator==(ExtInfo Other) const { @@ -2394,8 +2575,17 @@ class FunctionType : public Type { return ExtInfo(Bits & ~NoReturnMask); } + ExtInfo withProducesResult(bool producesResult) const { + if (producesResult) + return ExtInfo(Bits | ProducesResultMask); + else + return ExtInfo(Bits & ~ProducesResultMask); + } + ExtInfo withRegParm(unsigned RegParm) const { - return ExtInfo(HasRegParmMask | (Bits & ~RegParmMask) | (RegParm << RegParmOffset)); + assert(RegParm < 7 && "Invalid regparm value"); + return ExtInfo((Bits & ~RegParmMask) | + ((RegParm + 1) << RegParmOffset)); } ExtInfo withCallingConv(CallingConv cc) const { @@ -2411,9 +2601,10 @@ protected: FunctionType(TypeClass tc, QualType res, bool variadic, unsigned typeQuals, RefQualifierKind RefQualifier, QualType Canonical, bool Dependent, + bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack, ExtInfo Info) - : Type(tc, Canonical, Dependent, VariablyModified, + : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, ContainsUnexpandedParameterPack), ResultType(res) { FunctionTypeBits.ExtInfo = Info.Bits; @@ -2458,7 +2649,8 @@ public: class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) : FunctionType(FunctionNoProto, Result, false, 0, RQ_None, Canonical, - /*Dependent=*/false, Result->isVariablyModifiedType(), + /*Dependent=*/false, /*InstantiationDependent=*/false, + Result->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false, Info) {} friend class ASTContext; // ASTContext creates these. @@ -2495,7 +2687,8 @@ public: struct ExtProtoInfo { ExtProtoInfo() : Variadic(false), ExceptionSpecType(EST_None), TypeQuals(0), - RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0) {} + RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0), + ConsumedArguments(0) {} FunctionType::ExtInfo ExtInfo; bool Variadic; @@ -2505,6 +2698,7 @@ public: unsigned NumExceptions; const QualType *Exceptions; Expr *NoexceptExpr; + const bool *ConsumedArguments; }; private: @@ -2523,7 +2717,7 @@ private: QualType canonical, const ExtProtoInfo &epi); /// NumArgs - The number of arguments this function has, not counting '...'. - unsigned NumArgs : 20; + unsigned NumArgs : 19; /// NumExceptions - The number of types in the exception spec, if any. unsigned NumExceptions : 9; @@ -2531,6 +2725,9 @@ private: /// ExceptionSpecType - The type of exception specification this function has. unsigned ExceptionSpecType : 3; + /// HasAnyConsumedArgs - Whether this function has any consumed arguments. + unsigned HasAnyConsumedArgs : 1; + /// ArgInfo - There is an variable size array after the class in memory that /// holds the argument types. @@ -2540,8 +2737,25 @@ private: /// NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing /// to the expression in the noexcept() specifier. + /// ConsumedArgs - A variable size array, following Exceptions + /// and of length NumArgs, holding flags indicating which arguments + /// are consumed. This only appears if HasAnyConsumedArgs is true. + friend class ASTContext; // ASTContext creates these. + const bool *getConsumedArgsBuffer() const { + assert(hasAnyConsumedArgs()); + + // Find the end of the exceptions. + Expr * const *eh_end = reinterpret_cast<Expr * const *>(arg_type_end()); + if (getExceptionSpecType() != EST_ComputedNoexcept) + eh_end += NumExceptions; + else + eh_end += 1; // NoexceptExpr + + return reinterpret_cast<const bool*>(eh_end); + } + public: unsigned getNumArgs() const { return NumArgs; } QualType getArgType(unsigned i) const { @@ -2562,6 +2776,8 @@ public: } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { EPI.NoexceptExpr = getNoexceptExpr(); } + if (hasAnyConsumedArgs()) + EPI.ConsumedArguments = getConsumedArgsBuffer(); return EPI; } @@ -2647,6 +2863,16 @@ public: return exception_begin() + NumExceptions; } + bool hasAnyConsumedArgs() const { + return HasAnyConsumedArgs; + } + bool isArgConsumed(unsigned I) const { + assert(I < getNumArgs() && "argument index out of range!"); + if (hasAnyConsumedArgs()) + return getConsumedArgsBuffer()[I]; + return false; + } + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2670,7 +2896,7 @@ class UnresolvedUsingType : public Type { UnresolvedUsingTypenameDecl *Decl; UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) - : Type(UnresolvedUsing, QualType(), true, false, + : Type(UnresolvedUsing, QualType(), true, true, false, /*ContainsUnexpandedParameterPack=*/false), Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {} friend class ASTContext; // ASTContext creates these. @@ -2700,7 +2926,9 @@ class TypedefType : public Type { TypedefNameDecl *Decl; protected: TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) - : Type(tc, can, can->isDependentType(), can->isVariablyModifiedType(), + : Type(tc, can, can->isDependentType(), + can->isInstantiationDependentType(), + can->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false), Decl(const_cast<TypedefNameDecl*>(D)) { assert(!isa<TypedefType>(can) && "Invalid canonical type"); @@ -2731,7 +2959,7 @@ public: QualType desugar() const; /// \brief Returns whether this type directly provides sugar. - bool isSugared() const { return true; } + bool isSugared() const; static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } static bool classof(const TypeOfExprType *) { return true; } @@ -2751,9 +2979,6 @@ public: DependentTypeOfExprType(const ASTContext &Context, Expr *E) : TypeOfExprType(E), Context(Context) { } - bool isSugared() const { return false; } - QualType desugar() const { return QualType(this, 0); } - void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Context, getUnderlyingExpr()); } @@ -2766,7 +2991,9 @@ public: class TypeOfType : public Type { QualType TOType; TypeOfType(QualType T, QualType can) - : Type(TypeOf, can, T->isDependentType(), T->isVariablyModifiedType(), + : Type(TypeOf, can, T->isDependentType(), + T->isInstantiationDependentType(), + T->isVariablyModifiedType(), T->containsUnexpandedParameterPack()), TOType(T) { assert(!isa<TypedefType>(can) && "Invalid canonical type"); @@ -2802,10 +3029,10 @@ public: QualType getUnderlyingType() const { return UnderlyingType; } /// \brief Remove a single level of sugar. - QualType desugar() const { return getUnderlyingType(); } + QualType desugar() const; /// \brief Returns whether this type directly provides sugar. - bool isSugared() const { return !isDependentType(); } + bool isSugared() const; static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } static bool classof(const DecltypeType *) { return true; } @@ -2823,9 +3050,6 @@ class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { public: DependentDecltypeType(const ASTContext &Context, Expr *E); - bool isSugared() const { return false; } - QualType desugar() const { return QualType(this, 0); } - void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Context, getUnderlyingExpr()); } @@ -2971,6 +3195,7 @@ public: // Enumerated operand (string or keyword). attr_objc_gc, + attr_objc_ownership, attr_pcs, FirstEnumOperandKind = attr_objc_gc, @@ -2994,6 +3219,7 @@ private: AttributedType(QualType canon, Kind attrKind, QualType modified, QualType equivalent) : Type(Attributed, canon, canon->isDependentType(), + canon->isInstantiationDependentType(), canon->isVariablyModifiedType(), canon->containsUnexpandedParameterPack()), ModifiedType(modified), EquivalentType(equivalent) { @@ -3046,13 +3272,16 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { /// Build a non-canonical type. TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) : Type(TemplateTypeParm, Canon, /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariablyModified=*/false, Canon->containsUnexpandedParameterPack()), TTPDecl(TTPDecl) { } /// Build the canonical type. TemplateTypeParmType(unsigned D, unsigned I, bool PP) - : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true, + : Type(TemplateTypeParm, QualType(this, 0), + /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariablyModified=*/false, PP) { CanTTPTInfo.Depth = D; CanTTPTInfo.Index = I; @@ -3112,6 +3341,7 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), + Canon->isInstantiationDependentType(), Canon->isVariablyModifiedType(), Canon->containsUnexpandedParameterPack()), Replaced(Param) { } @@ -3211,6 +3441,7 @@ class AutoType : public Type, public llvm::FoldingSetNode { AutoType(QualType DeducedType) : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, /*Dependent=*/DeducedType.isNull(), + /*InstantiationDependent=*/DeducedType.isNull(), /*VariablyModified=*/false, /*ContainsParameterPack=*/false) { assert((DeducedType.isNull() || !DeducedType->isDependentType()) && "deduced a dependent type for auto"); @@ -3244,28 +3475,35 @@ public: static bool classof(const AutoType *T) { return true; } }; -/// \brief Represents the type of a template specialization as written -/// in the source code. +/// \brief Represents a type template specialization; the template +/// must be a class template, a type alias template, or a template +/// template parameter. A template which cannot be resolved to one of +/// these, e.g. because it is written with a dependent scope +/// specifier, is instead represented as a +/// @c DependentTemplateSpecializationType. /// -/// Template specialization types represent the syntactic form of a -/// template-id that refers to a type, e.g., @c vector<int>. Some -/// template specialization types are syntactic sugar, whose canonical -/// type will point to some other type node that represents the -/// instantiation or class template specialization. For example, a -/// class template specialization type of @c vector<int> will refer to -/// a tag type for the instantiation -/// @c std::vector<int, std::allocator<int>>. +/// A non-dependent template specialization type is always "sugar", +/// typically for a @c RecordType. For example, a class template +/// specialization type of @c vector<int> will refer to a tag type for +/// the instantiation @c std::vector<int, std::allocator<int>> /// -/// Other template specialization types, for which the template name -/// is dependent, may be canonical types. These types are always -/// dependent. +/// Template specializations are dependent if either the template or +/// any of the template arguments are dependent, in which case the +/// type may also be canonical. /// -/// An instance of this type is followed by an array of TemplateArgument*s, -/// then, if the template specialization type is for a type alias template, -/// a QualType representing the non-canonical aliased type. +/// Instances of this type are allocated with a trailing array of +/// TemplateArguments, followed by a QualType representing the +/// non-canonical aliased type when the template is a type alias +/// template. class TemplateSpecializationType : public Type, public llvm::FoldingSetNode { - /// \brief The name of the template being specialized. + /// \brief The name of the template being specialized. This is + /// either a TemplateName::Template (in which case it is a + /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a + /// TypeAliasTemplateDecl*), a + /// TemplateName::SubstTemplateTemplateParmPack, or a + /// TemplateName::SubstTemplateTemplateParm (in which case the + /// replacement must, recursively, be one of these). TemplateName Template; /// \brief - The number of template arguments named in this class @@ -3283,12 +3521,15 @@ public: /// \brief Determine whether any of the given template arguments are /// dependent. static bool anyDependentTemplateArguments(const TemplateArgument *Args, - unsigned NumArgs); + unsigned NumArgs, + bool &InstantiationDependent); static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, - unsigned NumArgs); + unsigned NumArgs, + bool &InstantiationDependent); - static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &); + static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &, + bool &InstantiationDependent); /// \brief Print a template argument list, including the '<' and '>' /// enclosing the template arguments. @@ -3399,6 +3640,7 @@ class InjectedClassNameType : public Type { // interdependencies. InjectedClassNameType(CXXRecordDecl *D, QualType TST) : Type(InjectedClassName, QualType(), /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariablyModified=*/false, /*ContainsUnexpandedParameterPack=*/false), Decl(D), InjectedType(TST) { @@ -3461,9 +3703,10 @@ enum ElaboratedTypeKeyword { class TypeWithKeyword : public Type { protected: TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, - QualType Canonical, bool Dependent, bool VariablyModified, + QualType Canonical, bool Dependent, + bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack) - : Type(tc, Canonical, Dependent, VariablyModified, + : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, ContainsUnexpandedParameterPack) { TypeWithKeywordBits.Keyword = Keyword; } @@ -3523,6 +3766,7 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { QualType NamedType, QualType CanonType) : TypeWithKeyword(Keyword, Elaborated, CanonType, NamedType->isDependentType(), + NamedType->isInstantiationDependentType(), NamedType->isVariablyModifiedType(), NamedType->containsUnexpandedParameterPack()), NNS(NNS), NamedType(NamedType) { @@ -3585,6 +3829,7 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType CanonType) : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariablyModified=*/false, NNS->containsUnexpandedParameterPack()), NNS(NNS), Name(Name) { @@ -3738,6 +3983,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode { PackExpansionType(QualType Pattern, QualType Canon, llvm::Optional<unsigned> NumExpansions) : Type(PackExpansion, Canon, /*Dependent=*/true, + /*InstantiationDependent=*/true, /*VariableModified=*/Pattern->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false), Pattern(Pattern), @@ -3829,7 +4075,7 @@ protected: enum Nonce_ObjCInterface { Nonce_ObjCInterface }; ObjCObjectType(enum Nonce_ObjCInterface) - : Type(ObjCInterface, QualType(), false, false, false), + : Type(ObjCInterface, QualType(), false, false, false, false), BaseType(QualType(this_(), 0)) { ObjCObjectTypeBits.NumProtocols = 0; } @@ -3986,7 +4232,7 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; ObjCObjectPointerType(QualType Canonical, QualType Pointee) - : Type(ObjCObjectPointer, Canonical, false, false, false), + : Type(ObjCObjectPointer, Canonical, false, false, false, false), PointeeType(Pointee) {} friend class ASTContext; // ASTContext creates these. @@ -4303,6 +4549,11 @@ inline QualType QualType::getNonReferenceType() const { return *this; } +inline bool QualType::isCForbiddenLValueType() const { + return ((getTypePtr()->isVoidType() && !hasQualifiers()) || + getTypePtr()->isFunctionType()); +} + /// \brief Tests whether the type is categorized as a fundamental type. /// /// \returns True for types specified in C++0x [basic.fundamental]. @@ -4480,6 +4731,11 @@ inline bool Type::isOverloadableType() const { return isDependentType() || isRecordType() || isEnumeralType(); } +/// \brief Determines whether this type can decay to a pointer type. +inline bool Type::canDecayToPointerType() const { + return isFunctionType() || isArrayType(); +} + inline bool Type::hasPointerRepresentation() const { return (isPointerType() || isReferenceType() || isBlockPointerType() || isObjCObjectPointerType() || isNullPtrType()); diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h index b966f3a..badb493 100644 --- a/include/clang/Analysis/Analyses/UninitializedValues.h +++ b/include/clang/Analysis/Analyses/UninitializedValues.h @@ -32,10 +32,16 @@ public: const VarDecl *vd, bool isAlwaysUninit) {} }; - + +struct UninitVariablesAnalysisStats { + unsigned NumVariablesAnalyzed; + unsigned NumBlockVisits; +}; + void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg, AnalysisContext &ac, - UninitVariablesHandler &handler); + UninitVariablesHandler &handler, + UninitVariablesAnalysisStats &stats); } #endif diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h index 66c12a5..6a1876e 100644 --- a/include/clang/Analysis/AnalysisContext.h +++ b/include/clang/Analysis/AnalysisContext.h @@ -107,6 +107,11 @@ public: void dumpCFG(); + /// \brief Returns true if we have built a CFG for this analysis context. + /// Note that this doesn't correspond to whether or not a valid CFG exists, it + /// corresponds to whether we *attempted* to build one. + bool isCFGBuilt() const { return builtCFG; } + ParentMap &getParentMap(); PseudoConstantAnalysis *getPseudoConstantAnalysis(); LiveVariables *getLiveVariables(); diff --git a/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/include/clang/Analysis/DomainSpecific/CocoaConventions.h index 18e81fe..5a4e06f 100644 --- a/include/clang/Analysis/DomainSpecific/CocoaConventions.h +++ b/include/clang/Analysis/DomainSpecific/CocoaConventions.h @@ -7,34 +7,45 @@ // //===----------------------------------------------------------------------===// // -// This file defines +// This file implements cocoa naming convention analysis. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_ANALYSIS_DS_COCOA #define LLVM_CLANG_ANALYSIS_DS_COCOA +#include "llvm/ADT/StringRef.h" #include "clang/AST/Type.h" namespace clang { + +class ObjCMethodDecl; + namespace ento { namespace cocoa { enum NamingConvention { NoConvention, CreateRule, InitRule }; - NamingConvention deriveNamingConvention(Selector S); + NamingConvention deriveNamingConvention(Selector S, const ObjCMethodDecl *MD); - static inline bool followsFundamentalRule(Selector S) { - return deriveNamingConvention(S) == CreateRule; + static inline bool followsFundamentalRule(Selector S, + const ObjCMethodDecl *MD) { + return deriveNamingConvention(S, MD) == CreateRule; } bool isRefType(QualType RetTy, llvm::StringRef Prefix, llvm::StringRef Name = llvm::StringRef()); - + + bool isCocoaObjectRef(QualType T); + +} + +namespace coreFoundation { bool isCFObjectRef(QualType T); - bool isCocoaObjectRef(QualType T); + bool followsCreateRule(llvm::StringRef functionName); +} -}}} +}} // end: "clang:ento" #endif diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index e4c6722..e64dc6a 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -400,6 +400,11 @@ def ObjCNSObject : InheritableAttr { let Spellings = ["NSObject"]; } +def ObjCPreciseLifetime : Attr { + let Spellings = ["objc_precise_lifetime"]; + let Subjects = [Var]; +} + def Overloadable : Attr { let Spellings = ["overloadable"]; } @@ -479,6 +484,10 @@ def Unavailable : InheritableAttr { let Args = [StringArgument<"Message">]; } +def ArcWeakrefUnavailable : InheritableAttr { + let Spellings = ["objc_arc_weak_reference_unavailable"]; +} + def Unused : InheritableAttr { let Spellings = ["unused"]; } diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index 9a4c768..a3cc615 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -604,6 +604,8 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn") // Microsoft builtins. BUILTIN(__assume, "vb", "n") BUILTIN(__noop, "v.", "n") +BUILTIN(__debugbreak, "v", "n") + // C99 library functions // C99 stdlib.h @@ -727,6 +729,10 @@ 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(fma, "dddd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmal, "LdLdLdLd", "fc", "math.h", ALL_LANGUAGES) +LIBBUILTIN(fmaf, "ffff", "fc", "math.h", ALL_LANGUAGES) + // Blocks runtime Builtin math library functions LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES) LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES) diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h index 0d17e03..7469e14 100644 --- a/include/clang/Basic/Builtins.h +++ b/include/clang/Basic/Builtins.h @@ -50,7 +50,6 @@ enum ID { struct Info { const char *Name, *Type, *Attributes, *HeaderName; LanguageID builtin_lang; - bool Suppressed; bool operator==(const Info &RHS) const { return !strcmp(Name, RHS.Name) && diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index 6ef667d..6bd9014 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -26,6 +26,7 @@ // 3DNow! // +BUILTIN(__builtin_ia32_femms, "v", "") BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "nc") BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "nc") BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "nc") @@ -47,7 +48,7 @@ BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "nc") BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "nc") BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "nc") BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "nc") -// 3DNow! Extensions. +// 3DNow! Extensions (3dnowa). BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "nc") BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "nc") BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "nc") @@ -57,15 +58,13 @@ BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "nc") // MMX // -// FIXME: All MMX instructions will be generated via builtins. Any MMX vector +// All MMX instructions will be generated via builtins. Any MMX vector // types (<1 x i64>, <2 x i32>, etc.) that aren't used by these builtins will be // expanded by the back-end. BUILTIN(__builtin_ia32_emms, "v", "") -BUILTIN(__builtin_ia32_femms, "v", "") BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "") BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "") @@ -73,27 +72,17 @@ BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "") BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "") BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "") BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "") BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "") BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "") BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "") -BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "") BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "") BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "") BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "") @@ -113,7 +102,6 @@ BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "") BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "") BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "") BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "") -BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "") BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "") @@ -127,14 +115,53 @@ BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "") BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "") -BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "") BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "") -BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "") BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "") BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "") BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "") BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "") +// MMX2 (MMX+SSE) intrinsics +BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "") +BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "") +BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "") +BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "") +BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "") +BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "") +BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "") +BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "") +BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "") + +// MMX+SSE2 +BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "") +BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "") +BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "") +BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "") +BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "") +BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "") + +// MMX+SSSE3 +BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "") +BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "") +BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "") +BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "") +BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "") +BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "") +BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "") +BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "") +BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "") +BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "") +BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "") + // SSE intrinsics. BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "") BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "") @@ -204,42 +231,24 @@ BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "") BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "") BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "") BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "") BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "") BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_pmaddubsw128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "") BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "") -BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "") BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "") -BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "") BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "") -BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "") BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "") BUILTIN(__builtin_ia32_stmxcsr, "Ui", "") -BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "") -BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "") BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "") BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "") -BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "") BUILTIN(__builtin_ia32_storeups, "vf*V4f", "") BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "") BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "") @@ -265,11 +274,8 @@ BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "") BUILTIN(__builtin_ia32_cvtdq2pd, "V2dV4i", "") BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "") BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "") -BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "") BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "") BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "") -BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "") -BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "") BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "") BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "") BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "") diff --git a/include/clang/Basic/DelayedCleanupPool.h b/include/clang/Basic/DelayedCleanupPool.h new file mode 100644 index 0000000..843205f --- /dev/null +++ b/include/clang/Basic/DelayedCleanupPool.h @@ -0,0 +1,109 @@ +//=== DelayedCleanupPool.h - Delayed Clean-up Pool Implementation *- 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 a facility to delay calling cleanup methods until specific +// points. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H +#define LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" + +namespace clang { + +/// \brief Gathers pairs of pointer-to-object/pointer-to-cleanup-function +/// allowing the cleanup functions to get called (with the pointer as parameter) +/// at specific points. +/// +/// The use case is to simplify clean-up of certain resources that, while their +/// lifetime is well-known and restricted, cleaning them up manually is easy to +/// miss and cause a leak. +/// +/// The same pointer can be added multiple times; its clean-up function will +/// only be called once. +class DelayedCleanupPool { +public: + typedef void (*CleanupFn)(void *ptr); + + /// \brief Adds a pointer and its associated cleanup function to be called + /// at a later point. + /// + /// \returns false if the pointer is already added, true otherwise. + bool delayCleanup(void *ptr, CleanupFn fn) { + assert(ptr && "Expected valid pointer to object"); + assert(fn && "Expected valid pointer to function"); + + CleanupFn &mapFn = Ptrs[ptr]; + assert((!mapFn || mapFn == fn) && + "Adding a pointer with different cleanup function!"); + + if (!mapFn) { + mapFn = fn; + Cleanups.push_back(std::make_pair(ptr, fn)); + return true; + } + + return false; + } + + template <typename T> + bool delayDelete(T *ptr) { + return delayCleanup(ptr, cleanupWithDelete<T>); + } + + template <typename T, void (T::*Fn)()> + bool delayMemberFunc(T *ptr) { + return delayCleanup(ptr, cleanupWithMemberFunc<T, Fn>); + } + + void doCleanup() { + for (llvm::SmallVector<std::pair<void *, CleanupFn>, 8>::reverse_iterator + I = Cleanups.rbegin(), E = Cleanups.rend(); I != E; ++I) + I->second(I->first); + Cleanups.clear(); + Ptrs.clear(); + } + + ~DelayedCleanupPool() { + doCleanup(); + } + +private: + llvm::DenseMap<void *, CleanupFn> Ptrs; + llvm::SmallVector<std::pair<void *, CleanupFn>, 8> Cleanups; + + template <typename T> + static void cleanupWithDelete(void *ptr) { + delete static_cast<T *>(ptr); + } + + template <typename T, void (T::*Fn)()> + static void cleanupWithMemberFunc(void *ptr) { + (static_cast<T *>(ptr)->*Fn)(); + } +}; + +/// \brief RAII object for triggering a cleanup of a DelayedCleanupPool. +class DelayedCleanupPoint { + DelayedCleanupPool &Pool; + +public: + DelayedCleanupPoint(DelayedCleanupPool &pool) : Pool(pool) { } + + ~DelayedCleanupPoint() { + Pool.doCleanup(); + } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index fa76324..6f72976 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -251,6 +251,14 @@ private: bool ErrorOccurred; bool FatalErrorOccurred; + /// \brief Indicates that an unrecoverable error has occurred. + bool UnrecoverableErrorOccurred; + + /// \brief Toggles for DiagnosticErrorTrap to check whether an error occurred + /// during a parsing section, e.g. during parsing a function. + bool TrapErrorOccurred; + bool TrapUnrecoverableErrorOccurred; + /// LastDiagLevel - This is the level of the last diagnostic emitted. This is /// used to emit continuation diagnostics with the same level as the /// diagnostic that they follow. @@ -269,13 +277,15 @@ private: /// can use this information to avoid redundancy across arguments. /// /// This is a hack to avoid a layering violation between libbasic and libsema. - typedef void (*ArgToStringFnTy)(ArgumentKind Kind, intptr_t Val, - const char *Modifier, unsigned ModifierLen, - const char *Argument, unsigned ArgumentLen, - const ArgumentValue *PrevArgs, - unsigned NumPrevArgs, - llvm::SmallVectorImpl<char> &Output, - void *Cookie); + typedef void (*ArgToStringFnTy)( + ArgumentKind Kind, intptr_t Val, + const char *Modifier, unsigned ModifierLen, + const char *Argument, unsigned ArgumentLen, + const ArgumentValue *PrevArgs, + unsigned NumPrevArgs, + llvm::SmallVectorImpl<char> &Output, + void *Cookie, + llvm::SmallVectorImpl<intptr_t> &QualTypeVals); void *ArgToStringCookie; ArgToStringFnTy ArgToStringFn; @@ -432,7 +442,12 @@ public: bool hasErrorOccurred() const { return ErrorOccurred; } bool hasFatalErrorOccurred() const { return FatalErrorOccurred; } - + + /// \brief Determine whether any kind of unrecoverable error has occurred. + bool hasUnrecoverableErrorOccurred() const { + return FatalErrorOccurred || UnrecoverableErrorOccurred; + } + unsigned getNumWarnings() const { return NumWarnings; } void setNumWarnings(unsigned NumWarnings) { @@ -452,9 +467,11 @@ public: const char *Modifier, unsigned ModLen, const char *Argument, unsigned ArgLen, const ArgumentValue *PrevArgs, unsigned NumPrevArgs, - llvm::SmallVectorImpl<char> &Output) const { + llvm::SmallVectorImpl<char> &Output, + llvm::SmallVectorImpl<intptr_t> &QualTypeVals) const { ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, - PrevArgs, NumPrevArgs, Output, ArgToStringCookie); + PrevArgs, NumPrevArgs, Output, ArgToStringCookie, + QualTypeVals); } void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) { @@ -621,20 +638,28 @@ private: /// queried. class DiagnosticErrorTrap { Diagnostic &Diag; - unsigned PrevErrors; public: explicit DiagnosticErrorTrap(Diagnostic &Diag) - : Diag(Diag), PrevErrors(Diag.NumErrors) {} + : Diag(Diag) { reset(); } /// \brief Determine whether any errors have occurred since this /// object instance was created. bool hasErrorOccurred() const { - return Diag.NumErrors > PrevErrors; + return Diag.TrapErrorOccurred; + } + + /// \brief Determine whether any unrecoverable errors have occurred since this + /// object instance was created. + bool hasUnrecoverableErrorOccurred() const { + return Diag.TrapUnrecoverableErrorOccurred; } // Set to initial state of "no errors occurred". - void reset() { PrevErrors = Diag.NumErrors; } + void reset() { + Diag.TrapErrorOccurred = false; + Diag.TrapUnrecoverableErrorOccurred = false; + } }; //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticCategories.h b/include/clang/Basic/DiagnosticCategories.h new file mode 100644 index 0000000..4dd067b --- /dev/null +++ b/include/clang/Basic/DiagnosticCategories.h @@ -0,0 +1,26 @@ +//===- DiagnosticCategories.h - Diagnostic Categories Enumerators-*- C++ -*===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_DIAGNOSTICCATEGORIES_H +#define LLVM_CLANG_BASIC_DIAGNOSTICCATEGORIES_H + +namespace clang { + namespace diag { + enum { +#define GET_CATEGORY_TABLE +#define CATEGORY(X, ENUM) ENUM, +#include "clang/Basic/DiagnosticGroups.inc" +#undef CATEGORY +#undef GET_CATEGORY_TABLE + DiagCat_NUM_CATEGORIES + }; + } // end namespace diag +} // end namespace clang + +#endif diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 50110fb..4b5de36 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -32,6 +32,7 @@ def note_type_being_defined : Note< def note_matching : Note<"to match this '%0'">; def note_using : Note<"using">; +def note_possibility : Note<"one possibility">; def note_also_found : Note<"also found">; // Parse && Lex diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 908a69b..e33b67e 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -82,6 +82,12 @@ def err_drv_conflicting_deployment_targets : Error< "conflicting deployment targets, both '%0' and '%1' are present in environment">; def err_drv_invalid_arch_for_deployment_target : Error< "invalid architecture '%0' for deployment target '%1'">; +def err_drv_objc_gc_arr : Error< + "cannot specify both '-fobjc-arc' and '%0'">; +def err_arc_nonfragile_abi : Error< + "-fobjc-arc is not supported with fragile abi">; +def err_drv_mg_requires_m_or_mm : Error< + "option '-MG' requires '-M' or '-MM'">; def warn_c_kext : Warning< "ignoring -fapple-kext which is valid for c++ and objective-c++ only">; diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 4aa8513..120ba67 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -137,6 +137,9 @@ def warn_pch_nonfragile_abi2 : Error< "PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 " "Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 " "Objective-C ABI is selected">; +def warn_pch_auto_ref_count : Error< + "PCH file was compiled %select{without|with} automated reference counting," + "which is currently %select{disabled|enabled}">; def warn_pch_apple_kext : Error< "PCH file was compiled %select{with|without}0 support for Apple's kernel " "extensions ABI but it is currently %select{disabled|enabled}1">; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 9abd6d3..8a10914 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -62,6 +62,7 @@ def ExitTimeDestructors : DiagGroup<"exit-time-destructors">; def FourByteMultiChar : DiagGroup<"four-char-constants">; def GlobalConstructors : DiagGroup<"global-constructors">; def : DiagGroup<"idiomatic-parentheses">; +def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">; def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">; def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">; def : DiagGroup<"import">; @@ -115,6 +116,7 @@ def SignCompare : DiagGroup<"sign-compare">; def : DiagGroup<"stack-protector">; def : DiagGroup<"switch-default">; def : DiagGroup<"synth">; +def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">; def TautologicalCompare : DiagGroup<"tautological-compare">; def HeaderHygiene : DiagGroup<"header-hygiene">; @@ -168,6 +170,15 @@ def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">; def CustomAtomic : DiagGroup<"custom-atomic-properties">; def AtomicProperties : DiagGroup<"atomic-properties", [ImplicitAtomic, CustomAtomic]>; +def AutomaticReferenceCountingABI : DiagGroup<"arc-abi">; +def ARCUnsafeRetainedAssign : DiagGroup<"arc-unsafe-retained-assign">; +def ARCRetainCycles : DiagGroup<"arc-retain-cycles">; +def ARCNonPodMemAccess : DiagGroup<"arc-non-pod-memaccess">; +def AutomaticReferenceCounting : DiagGroup<"arc", + [AutomaticReferenceCountingABI, + ARCUnsafeRetainedAssign, + ARCRetainCycles, + ARCNonPodMemAccess]>; def Selector : DiagGroup<"selector">; def NonfragileAbi2 : DiagGroup<"nonfragile-abi2">; def Protocol : DiagGroup<"protocol">; @@ -192,7 +203,8 @@ def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">; // in -Wparentheses because most users who use -Wparentheses explicitly // do not want these warnings. def Parentheses : DiagGroup<"parentheses", - [LogicalOpParentheses]>; + [LogicalOpParentheses, + BitwiseOpParentheses]>; // -Wconversion has its own warnings, but we split a few out for // legacy reasons: @@ -217,12 +229,12 @@ def Unused : DiagGroup<"unused", // Format settings. def FormatSecurity : DiagGroup<"format-security">; +def FormatY2K : DiagGroup<"format-y2k">; def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull, - FormatSecurity]>, + FormatSecurity, FormatY2K]>, DiagCategory<"Format String Issue">; def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>; -def FormatY2K : DiagGroup<"format-y2k", [Format]>; def Format2 : DiagGroup<"format=2", [FormatNonLiteral, FormatSecurity, FormatY2K]>; @@ -248,6 +260,7 @@ def Most : DiagGroup<"most", [ ReturnType, SelfAssignment, Switch, + SizeofArrayArgument, Trigraphs, Uninitialized, UnknownPragmas, @@ -283,3 +296,6 @@ def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>; // A warning group for warnings about Microsoft extensions. def Microsoft : DiagGroup<"microsoft">; + +def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">; + diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index fa816de..ae4ed5b 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -227,6 +227,10 @@ private: /// suppressed. bool ProcessDiag(Diagnostic &Diag) const; + /// \brief Whether the diagnostic may leave the AST in a state where some + /// invariants can break. + bool isUnrecoverable(unsigned DiagID) const; + friend class Diagnostic; }; diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 3514cca..38d6a80 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -178,7 +178,7 @@ def ext_empty_fnmacro_arg : Extension< def err_pp_invalid_directive : Error<"invalid preprocessing directive">; def err_pp_hash_error : Error<"#error%0">; -def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal; +def warn_pp_file_not_found : Warning<"'%0' file not found">, DefaultFatal; def err_pp_error_opening_file : Error< "error opening file '%0': %1">, DefaultFatal; def err_pp_empty_filename : Error<"empty filename">; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index fb1c909..3764a40 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -263,6 +263,11 @@ def warn_objc_protocol_qualifier_missing_id : Warning< def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">; def err_illegal_super_cast : Error< "cannot cast 'super' (it isn't an expression)">; + +let CategoryName = "Automatic Reference Counting Issue" in { +def err_arc_bridge_retain : Error< + "unknown cast annotation __bridge_retain; did you mean __bridge_retained?">; +} def err_objc_illegal_visibility_spec : Error< "illegal visibility specification">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5cfa61b..97414f2 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -48,6 +48,8 @@ def err_vla_decl_has_static_storage : Error< "variable length array declaration can not have 'static' storage duration">; 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">; // C99 variably modified types def err_variably_modified_template_arg : Error< @@ -267,6 +269,15 @@ def warn_dyn_class_memaccess : Warning< InGroup<DiagGroup<"dynamic-class-memaccess">>; def note_bad_memaccess_silence : Note< "explicitly cast the pointer to silence this warning">; +def warn_sizeof_pointer_expr_memaccess : Warning< + "argument to 'sizeof' in %0 call is the same expression as the " + "%select{destination|source}1; did you mean to " + "%select{dereference it|remove the addressof|provide an explicit length}2?">, + InGroup<DiagGroup<"sizeof-pointer-memaccess">>; +def warn_sizeof_pointer_type_memaccess : Warning< + "argument to 'sizeof' in %0 call is the same pointer type %1 as the " + "%select{destination|source}2; expected %3 or an explicit length">, + InGroup<DiagGroup<"sizeof-pointer-memaccess">>; /// main() // static/inline main() are not errors in C, just in C++. @@ -319,6 +330,8 @@ def err_duplicate_class_def : Error< "duplicate interface definition for class %0">; def err_undef_superclass : Error< "cannot find interface declaration for %0, superclass of %1">; +def err_forward_superclass : Error< + "attempting to use the forward class %0 as superclass of %1">; def err_no_nsconstant_string_class : Error< "cannot find interface declaration for %0">; def err_recursive_superclass : Error< @@ -344,6 +357,8 @@ def err_class_extension_after_impl : Error< "cannot declare class extension for %0 after class implementation">; def note_implementation_declared : Note< "class implementation is declared here">; +def note_class_declared : Note< + "class is declared here">; def warn_dup_category_def : Warning< "duplicate definition of category %1 on interface %0">; def err_conflicting_super_class : Error<"conflicting super class name %0">; @@ -425,6 +440,15 @@ def warn_objc_property_copy_missing_on_block : Warning< def warn_atomic_property_rule : Warning< "writable atomic property %0 cannot pair a synthesized setter/getter " "with a user defined setter/getter">; +def warn_ownin_getter_rule : Warning< + "property's synthesized getter follows Cocoa naming" + " convention for returning 'owned' objects">; +def warn_property_getter_owning_mismatch : Warning< + "property declared as returning non-retained objects" + "; getter returning retained objects">; +def err_ownin_getter_rule : Error< + "property's synthesized getter follows Cocoa naming" + " convention for returning 'owned' objects">; def warn_default_atomic_custom_getter_setter : Warning< "atomic by default property %0 has a user defined %select{getter|setter}1 " "(property should be marked 'atomic' if this is intended)">, @@ -460,6 +484,12 @@ def error_bad_property_context : Error< def error_missing_property_ivar_decl : Error< "synthesized property %0 must either be named the same as a compatible" " ivar or must explicitly name an ivar">; +def error_synthesize_weak_non_arc_or_gc : Error< + "@synthesize of 'weak' property is only allowed in ARC or GC mode">; +def err_arc_perform_selector_retains : Error< + "performSelector names a selector which retains the object">; +def warn_arc_perform_selector_leaks : Warning< + "performSelector may cause a leak because its selector is unknown">; def error_synthesized_ivar_yet_not_supported : Error< "instance variable synthesis not yet supported" @@ -472,7 +502,7 @@ def error_ivar_in_superclass_use : Error< def error_weak_property : Error< "existing ivar %1 for __weak property %0 must be __weak">; def error_strong_property : Error< - "property %0 must be declared __weak to match existing ivar %1 with __weak attribute">; + "existing ivar %1 for strong property %0 may not be __weak">; def error_dynamic_property_ivar_decl : Error< "dynamic property can not have ivar specification">; def error_duplicate_ivar_use : Error< @@ -729,8 +759,6 @@ def err_not_integral_type_bitfield : Error< "bit-field %0 has non-integral type %1">; def err_not_integral_type_anon_bitfield : Error< "anonymous bit-field has non-integral type %0">; -def err_member_initialization : Error< - "fields can only be initialized in constructors">; def err_member_function_initialization : Error< "initializer on function does not look like a pure-specifier">; def err_non_virtual_pure : Error< @@ -1135,6 +1163,8 @@ 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_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">; @@ -1160,6 +1190,10 @@ def err_as_qualified_auto_decl : Error< "automatic variable qualified with an address space">; def err_arg_with_address_space : Error< "parameter may not be qualified with an address space">; +def err_attr_objc_ownership_bad_type : Error< + "the type %0 cannot be retained">; +def err_attr_objc_ownership_redundant : Error< + "the type %0 already has retainment attributes set on it">; def err_attribute_not_string : Error< "argument to %0 attribute was not a string literal">; def err_attribute_section_invalid_for_target : Error< @@ -1215,6 +1249,8 @@ def warn_function_attribute_wrong_type : Warning< "'%0' only applies to function types; type here is %1">; def warn_pointer_attribute_wrong_type : Warning< "'%0' only applies to pointer types; type here is %1">; +def warn_objc_object_attribute_wrong_type : Warning< + "'%0' only applies to objective-c object or block pointer types; type here is %1">; def warn_gnu_inline_attribute_requires_inline : Warning< "'gnu_inline' attribute requires function to be marked 'inline'," " attribute ignored">; @@ -1232,6 +1268,13 @@ def err_cconv_varargs : Error< def err_regparm_mismatch : Error<"function declared with with regparm(%0) " "attribute was previously declared " "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">; +def err_objc_precise_lifetime_bad_type : Error< + "objc_precise_lifetime only applies to retainable types; type here is %0">; +def warn_objc_precise_lifetime_meaningless : Error< + "objc_precise_lifetime is not meaningful for " + "%select{__unsafe_unretained|__autoreleasing}0 objects">; +def warn_label_attribute_not_unused : Warning< + "The only valid attribute for labels is 'unused'">; def err_invalid_pcs : Error<"Invalid PCS type">; // Availability attribute @@ -1505,7 +1548,13 @@ def note_ovl_candidate_arity : Note<"candidate " def note_ovl_candidate_deleted : Note< "candidate %select{function|function|constructor|" - "function |function |constructor ||||constructor (inherited)}0%1 " + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" + "constructor (inherited)}0%1 " "has been explicitly %select{made unavailable|deleted}2">; // Giving the index of the bad argument really clutters this message, and @@ -1565,7 +1614,18 @@ def note_ovl_candidate_bad_gc : Note<"candidate " "function (the implicit move assignment operator)|" "constructor (inherited)}0%1 not viable: " "%select{%ordinal6|'this'}5 argument (%2) has %select{no|__weak|__strong}3 " - "lifetime, but parameter has %select{no|__weak|__strong}4 lifetime">; + "ownership, but parameter has %select{no|__weak|__strong}4 ownership">; +def note_ovl_candidate_bad_ownership : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "function (the implicit copy assignment operator)|" + "constructor (inherited)}0%1 not viable: " + "%select{%ordinal6|'this'}5 argument (%2) has " + "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3 ownership," + " but parameter has %select{no|__unsafe_unretained|__strong|__weak|" + "__autoreleasing}4 ownership">; def note_ovl_candidate_bad_cvr_this : Note<"candidate " "%select{|function|||function||||" "function (the implicit copy assignment operator)|}0 not viable: " @@ -1871,8 +1931,11 @@ def err_not_class_template_specialization : Error< "parameter}0">; def err_function_specialization_in_class : Error< "cannot specialize a function %0 within class scope">; -def err_explicit_specialization_storage_class : Error< +def ext_explicit_specialization_storage_class : ExtWarn< "explicit specialization cannot have a storage class">; +def err_explicit_specialization_inconsistent_storage_class : Error< + "explicit specialization has extraneous, inconsistent storage class " + "'%select{none|extern|static|__private_extern__|auto|register}0'">; // C++ class template specializations and out-of-line definitions def err_template_spec_needs_header : Error< @@ -2180,7 +2243,7 @@ def err_undeclared_var_use : Error<"use of undeclared identifier %0">; def note_dependent_var_use : Note<"must qualify identifier to find this " "declaration in dependent base class">; def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither " - "visible in the template definition nor found by argument dependent lookup">; + "visible in the template definition nor found by argument-dependent lookup">; def note_not_found_by_two_phase_lookup : Note<"%0 should be declared prior to the " "call site%select{| or in %2| or in an associated namespace of one of its arguments}1">; def err_undeclared_use : Error<"use of undeclared %0">; @@ -2199,8 +2262,8 @@ def err_unavailable_message : Error<"%0 is unavailable: %1">; def warn_unavailable_fwdclass_message : Warning< "%0 maybe unavailable because receiver type is unknown">; def note_unavailable_here : Note< - "function has been explicitly marked " - "%select{unavailable|deleted|deprecated}0 here">; + "%select{declaration|function}0 has been explicitly marked " + "%select{unavailable|deleted|deprecated}1 here">; def warn_not_enough_argument : Warning< "not enough variable arguments in %0 declaration to fit a sentinel">; def warn_missing_sentinel : Warning < @@ -2237,6 +2300,8 @@ def err_inline_declaration_block_scope : Error< "inline declaration of %0 not allowed in block scope">; def err_static_non_static : Error< "static declaration of %0 follows non-static declaration">; +def warn_weak_import : Warning < + "an already-declared variable is made a weak_import declaration %0">; def warn_static_non_static : ExtWarn< "static declaration of %0 follows non-static declaration">; def err_non_static_static : Error< @@ -2418,6 +2483,8 @@ def err_indirect_goto_in_protected_scope : Error< def note_indirect_goto_target : Note<"possible target of indirect goto">; def note_protected_by_variable_init : Note< "jump bypasses variable initialization">; +def note_protected_by_variable_nontriv_destructor : Note< + "jump bypasses variable with a non-trivial destructor">; def note_protected_by_cleanup : Note< "jump bypasses initialization of variable with __attribute__((cleanup))">; def note_protected_by_vla_typedef : Note< @@ -2434,12 +2501,22 @@ def note_protected_by_objc_finally : Note< "jump bypasses initialization of @finally block">; def note_protected_by_objc_synchronized : Note< "jump bypasses initialization of @synchronized block">; +def note_protected_by_objc_autoreleasepool : Note< + "jump bypasses auto release push of @autoreleasepool block">; def note_protected_by_cxx_try : Note< "jump bypasses initialization of try block">; def note_protected_by_cxx_catch : Note< "jump bypasses initialization of catch block">; def note_protected_by___block : Note< "jump bypasses setup of __block variable">; +def note_protected_by_objc_ownership : Note< + "jump bypasses initialization of retaining variable">; +def note_enters_block_captures_cxx_obj : Note< + "jump enters lifetime of block which captures a destructible c++ object">; +def note_enters_block_captures_strong : Note< + "jump enters lifetime of block which strongly captures a variable">; +def note_enters_block_captures_weak : Note< + "jump enters lifetime of block which weakly captures a variable">; def note_exits_cleanup : Note< "jump exits scope of variable with __attribute__((cleanup))">; @@ -2459,6 +2536,16 @@ def note_exits_cxx_try : Note< "jump exits try block">; def note_exits_cxx_catch : Note< "jump exits catch block">; +def note_exits_objc_autoreleasepool : Note< + "jump exits autoreleasepool block">; +def note_exits_objc_ownership : Note< + "jump exits scope of retaining variable">; +def note_exits_block_captures_cxx_obj : Note< + "jump exits lifetime of block which captures a destructible c++ object">; +def note_exits_block_captures_strong : Note< + "jump exits lifetime of block which strongly captures a variable">; +def note_exits_block_captures_weak : Note< + "jump exits lifetime of block which weakly captures a variable">; def err_func_returning_array_function : Error< "function cannot return %select{array|function}0 type %1">; @@ -2490,6 +2577,152 @@ def ext_flexible_array_empty_aggregate_gnu : Extension< def ext_flexible_array_union_gnu : Extension< "flexible array member %0 in a union is a GNU extension">, InGroup<GNU>; +let CategoryName = "Automatic Reference Counting Issue" in { + +// ARC-mode diagnostics. +def err_arc_weak_no_runtime : Error< + "the current deployment target does not support automated __weak references">; +def err_arc_unsupported_weak_class : Error< + "class is incompatible with __weak references">; +def err_arc_weak_unavailable_assign : Error< + "assignment of a weak-unavailable object to a __weak object">; +def err_arc_convesion_of_weak_unavailable : Error< + "%select{implicit conversion|cast}0 of weak-unavailable object of type %1 to" + " a __weak object of type %2">; +def err_arc_illegal_explicit_message : Error< + "ARC forbids explicit message send of %0">; +def err_arc_unused_init_message : Error< + "the result of a delegate init call must be immediately returned " + "or assigned to 'self'">; +def err_arc_mismatched_cast : Error< + "%select{implicit conversion|cast}0 of " + "%select{%2|a non-Objective-C pointer type %2|a block pointer|" + "an Objective-C pointer|an indirect pointer to an Objective-C pointer}1" + " to %3 is disallowed with ARC">; +def err_arc_objc_object_in_struct : Error< + "ARC forbids Objective-C objects in structs or unions">; +def err_arc_objc_property_default_assign_on_object : Error< + "ARC forbids synthesizing a property of an Objective-C object " + "with unspecified storage attribute">; +def err_arc_illegal_selector : Error< + "ARC forbids use of %0 in a @selector">; +def err_arc_illegal_method_def : Error< + "ARC forbids implementation of %0">; +def err_arc_lost_method_convention : Error< + "method was declared as %select{an 'alloc'|a 'copy'|an 'init'|a 'new'}0 " + "method, but its implementation doesn't match because %select{" + "its result type is not an object pointer|" + "its result type is unrelated to its receiver type}1">; +def note_arc_lost_method_convention : Note<"declaration in interface">; +def err_arc_gained_method_convention : Error< + "method implementation does not match its declaration">; +def note_arc_gained_method_convention : Note< + "declaration in interface is not in the '%select{alloc|copy|init|new}0' " + "family because %select{its result type is not an object pointer|" + "its result type is unrelated to its receiver type}1">; +def err_typecheck_arr_assign_self : Error< + "cannot assign to 'self' outside of a method in the init family">; +def err_typecheck_arr_assign_enumeration : Error< + "fast enumeration variables can't be modified in ARC by default; " + "declare the variable __strong to allow this">; +def warn_arc_non_pod_class_with_object_member : Warning< + "%0 cannot be shared between ARC and non-ARC " + "code; add a copy constructor, a copy assignment operator, and a destructor " + "to make it ABI-compatible">, InGroup<AutomaticReferenceCountingABI>, + DefaultIgnore; +def warn_arc_retained_assign : Warning< + "assigning retained object to %select{weak|unsafe_unretained}0 variable" + "; object will be released after assignment">, + InGroup<ARCUnsafeRetainedAssign>; +def warn_arc_retained_property_assign : Warning< + "assigning retained object to unsafe property" + "; object will be released after assignment">, + InGroup<ARCUnsafeRetainedAssign>; +def warn_arc_trivial_member_function_with_object_member : Warning< + "%0 cannot be shared between ARC and non-ARC " + "code; add a non-trivial %select{copy constructor|copy assignment operator|" + "destructor}1 to make it ABI-compatible">, + InGroup<AutomaticReferenceCountingABI>, DefaultIgnore; +def err_arc_new_array_without_ownership : Error< + "'new' cannot allocate an array of %0 with no explicit ownership">; +def warn_err_new_delete_object_array : Warning< + "%select{allocating|destroying}0 an array of %1; this array must not " + "%select{be deleted in|have been allocated from}0 non-ARC code">, + InGroup<AutomaticReferenceCountingABI>, DefaultIgnore; +def err_arc_autoreleasing_var : Error< + "%select{__block variables|global variables|fields|ivars}0 cannot have " + "__autoreleasing ownership">; +def err_arc_thread_ownership : Error< + "thread-local variable has non-trivial ownership: type is %0">; +def err_arc_indirect_no_ownership : Error< + "%select{pointer|reference}1 to non-const type %0 with no explicit ownership">, + InGroup<AutomaticReferenceCounting>; +def err_arc_array_param_no_ownership : Error< + "must explicitly describe intended ownership of an object array parameter">; +def err_arc_pseudo_dtor_inconstant_quals : Error< + "pseudo-destructor destroys object of type %0 with inconsistently-qualified " + "type %1">; +def err_arc_init_method_unrelated_result_type : Error< + "init methods must return a type related to the receiver type">; +def err_arc_nonlocal_writeback : Error< + "passing address of %select{non-local|non-scalar}0 object to " + "__autoreleasing parameter for write-back">; +def err_arc_method_not_found : Error< + "no known %select{instance|class}1 method for selector %0">; +def err_arc_receiver_forward_class : Error< + "receiver %0 for class message is a forward declaration">; +def err_arc_may_not_respond : Error< + "receiver type %0 for instance message does not declare a method with " + "selector %1">; +def err_arc_receiver_forward_instance : Error< + "receiver type %0 for instance message is a forward declaration">; +def err_arc_multiple_method_decl : Error< + "multiple methods named %0 found with mismatched result, " + "parameter type or attributes">; +def warn_arc_retain_cycle : Warning< + "capturing %0 strongly in this block is likely to lead to a retain cycle">, + InGroup<ARCRetainCycles>; +def note_arc_retain_cycle_owner : Note< + "block will be retained by %select{the captured object|an object strongly " + "retained by the captured object}0">; +def note_nontrivial_objc_ownership : Note< + "because type %0 has %select{no|no|__strong|__weak|__autoreleasing}1 " + "ownership">; +def warn_arc_object_memaccess : Warning< + "%select{destination for|source of}0 this %1 call is a pointer to " + "ownership-qualified type %2">, InGroup<ARCNonPodMemAccess>; + +def err_arc_strong_property_ownership : Error< + "existing ivar %1 for strong property %0 may not be " + "%select{|__unsafe_unretained||__weak}2">; +def err_arc_assign_property_ownership : Error< + "existing ivar %1 for unsafe_unretained property %0 must be __unsafe_unretained">; +def err_arc_inconsistent_property_ownership : Error< + "%select{strong|weak|unsafe_unretained}1 property %0 may not also be " + "declared %select{|__unsafe_unretained|__strong|__weak|__autoreleasing}2">; +def err_arc_atomic_ownership : Error< + "cannot perform atomic operation on a pointer to type %0: type has " + "non-trivial ownership">; + +def err_arc_bridge_cast_incompatible : Error< + "incompatible types casting %0 to %1 with a %select{__bridge|" + "__bridge_transfer|__bridge_retained}2 cast">; +def err_arc_bridge_cast_wrong_kind : Error< + "cast of %select{Objective-C|block|C}0 pointer type %1 to " + "%select{Objective-C|block|C}2 pointer type %3 cannot use %select{__bridge|" + "__bridge_transfer|__bridge_retained}4">; +def err_arc_cast_requires_bridge : Error< + "cast of %select{Objective-C|block|C}0 pointer type %1 to " + "%select{Objective-C|block|C}2 pointer type %3 requires a bridged cast">; +def note_arc_bridge : Note< + "use __bridge to convert directly (no change in ownership)">; +def note_arc_bridge_transfer : Note< + "use __bridge_transfer to transfer ownership of a +1 %0 into ARC">; +def note_arc_bridge_retained : Note< + "use __bridge_retained to make an ARC object available as a +1 %0">; + +} // ARC category name + def err_flexible_array_init_needs_braces : Error< "flexible array requires brace-enclosed initializer">; def err_illegal_decl_array_of_functions : Error< @@ -2563,11 +2796,11 @@ def warn_remainder_by_zero : Warning<"remainder by zero is undefined">; def warn_shift_negative : Warning<"shift count is negative">; def warn_shift_gt_typewidth : Warning<"shift count >= width of type">; def warn_shift_result_gt_typewidth : Warning< - "shift result (%0) requires %1 bits to represent, but %2 only has %3 bits">, - InGroup<DiagGroup<"shift-overflow">>; -def warn_shift_result_overrides_sign_bit : Warning< - "shift result (%0) overrides the sign bit of the shift expression's type " - "(%1) and becomes negative">, + "signed shift result (%0) requires %1 bits to represent, but %2 only has " + "%3 bits">, InGroup<DiagGroup<"shift-overflow">>; +def warn_shift_result_sets_sign_bit : Warning< + "signed shift result (%0) sets the sign bit of the shift expression's " + "type (%1) and becomes negative">, InGroup<DiagGroup<"shift-sign-overflow">>, DefaultIgnore; def warn_precedence_bitwise_rel : Warning< @@ -2579,17 +2812,22 @@ def note_precedence_bitwise_silence : Note< "place parentheses around the %0 expression to silence this warning">; def warn_precedence_conditional : Warning< - "?: has lower precedence than %0; %0 will be evaluated first">, + "operator '?:' has lower precedence than '%0'; '%0' will be evaluated first">, InGroup<Parentheses>; def note_precedence_conditional_first : Note< - "place parentheses around the ?: expression to evaluate it first">; + "place parentheses around the '?:' expression to evaluate it first">; def note_precedence_conditional_silence : Note< - "place parentheses around the %0 expression to silence this warning">; + "place parentheses around the '%0' expression to silence this warning">; def warn_logical_instead_of_bitwise : Warning< "use of logical %0 with constant operand; switch to bitwise %1 or " "remove constant">, InGroup<DiagGroup<"constant-logical-operand">>; +def warn_bitwise_and_in_bitwise_or : Warning< + "'&' within '|'">, InGroup<BitwiseOpParentheses>; +def note_bitwise_and_in_bitwise_or_silence : Note< + "place parentheses around the '&' expression to silence this warning">; + def warn_logical_and_in_logical_or : Warning< "'&&' within '||'">, InGroup<LogicalOpParentheses>; def note_logical_and_in_logical_or_silence : Note< @@ -2599,6 +2837,10 @@ def warn_self_assignment : Warning< "explicitly assigning a variable of type %0 to itself">, InGroup<SelfAssignment>, DefaultIgnore; +def warn_sizeof_array_param : Warning< + "sizeof on array function parameter will return size of %0 instead of %1">, + InGroup<SizeofArrayArgument>; + def err_sizeof_nonfragile_interface : Error< "invalid application of '%select{alignof|sizeof}1' to interface %0 in " "non-fragile ABI">; @@ -2623,10 +2865,15 @@ def err_subscript_function_type : Error< "subscript of pointer to function type %0">; def err_subscript_incomplete_type : Error< "subscript of pointer to incomplete type %0">; +def ext_gnu_subscript_void_type : Extension< + "subscript of a pointer to void is a GNU extension">, InGroup<PointerArith>; def err_typecheck_member_reference_struct_union : Error< "member reference base type %0 is not a structure or union">; def err_typecheck_member_reference_ivar : Error< "%0 does not have a member named %1">; +def error_arc_weak_ivar_access : Error< + "dereferencing a __weak pointer is not allowed due to possible " + "null value caused by race condition, assign it to strong variable first">; def err_typecheck_member_reference_arrow : Error< "member reference type %0 is not a pointer">; def err_typecheck_member_reference_suggestion : Error< @@ -2658,7 +2905,7 @@ def err_member_def_undefined_record : Error< def err_member_def_does_not_match : Error< "out-of-line definition of %0 does not match any declaration in %1">; def err_member_def_does_not_match_ret_type : Error< - "out-of-line definition of %q0 differ from the declaration in the return type">; + "out-of-line definition of %q0 differs from the declaration in the return type">; def err_nonstatic_member_out_of_line : Error< "non-static data member defined out-of-line">; def err_nonstatic_flexible_variable : Error< @@ -2682,11 +2929,12 @@ def err_ivar_reference_type : Error< def err_typecheck_illegal_increment_decrement : Error< "cannot %select{decrement|increment}1 value of type %0">; def err_typecheck_arithmetic_incomplete_type : Error< - "arithmetic on pointer to incomplete type %0">; + "arithmetic on a pointer to an incomplete type %0">; def err_typecheck_pointer_arith_function_type : Error< - "arithmetic on pointer to function type %0">; + "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 " + "function type%select{|s}2 %1%select{| and %3}2">; def err_typecheck_pointer_arith_void_type : Error< - "arithmetic on pointer to void type">; + "arithmetic on%select{ a|}0 pointer%select{|s}0 to void">; def err_typecheck_decl_incomplete_type : Error< "variable has incomplete type %0">; def ext_typecheck_decl_incomplete_type : ExtWarn< @@ -2803,6 +3051,9 @@ def warn_runsigned_always_true_comparison : Warning< def warn_comparison_of_mixed_enum_types : Warning< "comparison of two values with different enumeration types (%0 and %1)">, InGroup<DiagGroup<"enum-compare">>; +def warn_null_in_arithmetic_operation : Warning< + "use of NULL in arithmetic operation">, + InGroup<DiagGroup<"null-arithmetic">>; def err_invalid_this_use : Error< "invalid use of 'this' outside of a nonstatic member function">; @@ -2871,9 +3122,11 @@ def note_forward_class : Note< def err_duplicate_property : Error< "property has a previous declaration">; def ext_gnu_void_ptr : Extension< - "use of GNU void* extension">, InGroup<PointerArith>; + "arithmetic on%select{ a|}0 pointer%select{|s}0 to void is a GNU extension">, + InGroup<PointerArith>; def ext_gnu_ptr_func_arith : Extension< - "arithmetic on pointer to function type %0 is a GNU extension">, + "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 function " + "type%select{|s}2 %1%select{| and %3}2 is a GNU extension">, InGroup<PointerArith>; def error_readonly_property_assignment : Error< "assigning to property with 'readonly' attribute not allowed">; @@ -2942,9 +3195,9 @@ def err_qualified_objc_catch_parm : Error< "@catch parameter declarator cannot be qualified">; def err_objc_pointer_cxx_catch_gnu : Error< "can't catch Objective C exceptions in C++ in the GNU runtime">; -def err_objc_pointer_cxx_catch_fragile : Error< - "can't catch Objective C exceptions in C++ in the non-unified " - "exception model">; +def warn_objc_pointer_cxx_catch_fragile : Warning< + "can not catch an exception thrown with @throw in C++ in the non-unified " + "exception model">, InGroup<ObjCNonUnifiedException>; def err_objc_object_catch : Error< "can't catch an Objective C object by value">; def err_incomplete_type_objc_at_encode : Error< @@ -3328,6 +3581,15 @@ def err_typecheck_incompatible_address_space : Error< "|sending %0 to parameter of type %1" "|casting %0 to type %1}2" " changes address space of pointer">; +def err_typecheck_incompatible_ownership : Error< + "%select{assigning %1 to %0" + "|passing %0 to parameter of type %1" + "|returning %0 from a function with result type %1" + "|converting %0 to type %1" + "|initializing %0 with an expression of type %1" + "|sending %0 to parameter of type %1" + "|casting %0 to type %1}2" + " changes retain/release properties of pointer">; def err_typecheck_convert_ambiguous : Error< "ambiguity in initializing value of type %0 with initializer of type %1">; def err_typecheck_comparison_of_distinct_blocks : Error< @@ -3544,6 +3806,9 @@ def ext_in_class_initializer_float_type : ExtWarn< def err_in_class_initializer_non_constant : Error< "in-class initializer is not a constant expression">; +def ext_in_class_initializer_non_constant : Extension< + "in-class initializer is not a constant expression, accepted as an extension">; + // C++ anonymous unions and GNU anonymous structs/unions def ext_anonymous_union : Extension< "anonymous unions are a GNU extension in C">, InGroup<GNU>; @@ -3929,12 +4194,23 @@ def err_switch_incomplete_class_type : Error< "switch condition has incomplete class type %0">; def warn_empty_if_body : Warning< "if statement has empty body">, InGroup<EmptyBody>; + 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">; 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< + "second argument to 'va_arg' is of incomplete type %0">; +def err_second_parameter_to_va_arg_abstract: Error< + "second argument to 'va_arg' is of abstract type %0">; +def warn_second_parameter_to_va_arg_not_pod : Warning< + "second argument to 'va_arg' is of non-POD type %0">, + InGroup<DiagGroup<"non-pod-varargs">>, DefaultError; +def warn_second_parameter_to_va_arg_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">; def warn_return_missing_expr : Warning< "non-void %select{function|method}1 %0 should return a value">, DefaultError, @@ -3943,8 +4219,9 @@ def ext_return_missing_expr : ExtWarn< "non-void %select{function|method}1 %0 should return a value">, DefaultError, InGroup<ReturnType>; def ext_return_has_expr : ExtWarn< - "void %select{function|method}1 %0 should not return a value">, DefaultError, - InGroup<ReturnType>; + "%select{void function|void method|constructor|destructor}1 %0 " + "should not return a value">, + DefaultError, InGroup<ReturnType>; def ext_return_has_void_expr : Extension< "void %select{function|method}1 %0 should not return void expression">; def warn_noreturn_function_has_return_expr : Warning< @@ -4074,6 +4351,11 @@ def err_typecheck_member_reference_ivar_suggest : Error< "%0 does not have a member named %1; did you mean %2?">; def err_property_not_found_suggest : Error< "property %0 not found on object of type %1; did you mean %2?">; +def err_ivar_access_using_property_syntax_suggest : Error< + "property %0 not found on object of type %1; did you mean to access ivar %2?">; +def err_property_found_suggest : Error< + "property %0 found on object of type %1; did you mean to access " + "it with the \".\" operator?">; def err_undef_interface_suggest : Error< "cannot find interface declaration for %0; did you mean %1?">; def warn_undef_interface_suggest : Warning< diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h index 2ca344d..1324533 100644 --- a/include/clang/Basic/FileManager.h +++ b/include/clang/Basic/FileManager.h @@ -21,10 +21,13 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/Allocator.h" -#include "llvm/Config/config.h" // for mode_t // FIXME: Enhance libsystem to support inode and other fields in stat. #include <sys/types.h> +#ifdef _MSC_VER +typedef unsigned short mode_t; +#endif + struct stat; namespace llvm { diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index b4eca6d..bebcffd 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -411,23 +411,15 @@ public: return II; } - IdentifierInfo &get(const char *NameStart, const char *NameEnd) { - return get(llvm::StringRef(NameStart, NameEnd-NameStart)); - } - - IdentifierInfo &get(const char *Name, size_t NameLen) { - return get(llvm::StringRef(Name, NameLen)); - } - /// \brief Gets an IdentifierInfo for the given name without consulting /// external sources. /// /// This is a version of get() meant for external sources that want to /// introduce or modify an identifier. If they called get(), they would /// likely end up in a recursion. - IdentifierInfo &getOwn(const char *NameStart, const char *NameEnd) { + IdentifierInfo &getOwn(llvm::StringRef Name) { llvm::StringMapEntry<IdentifierInfo*> &Entry = - HashTable.GetOrCreateValue(NameStart, NameEnd); + HashTable.GetOrCreateValue(Name); IdentifierInfo *II = Entry.getValue(); if (!II) { @@ -444,9 +436,6 @@ public: return *II; } - IdentifierInfo &getOwn(llvm::StringRef Name) { - return getOwn(Name.begin(), Name.end()); - } typedef HashTableTy::const_iterator iterator; typedef HashTableTy::const_iterator const_iterator; @@ -499,7 +488,10 @@ enum ObjCMethodFamily { OMF_release, OMF_retain, OMF_retainCount, - OMF_self + OMF_self, + + // performSelector families + OMF_performSelector }; /// Enough bits to store any enumerator in ObjCMethodFamily or diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index f0f1432..dc77d4c 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -119,6 +119,8 @@ public: unsigned InlineVisibilityHidden : 1; // Whether inline C++ methods have // hidden visibility by default. unsigned ParseUnknownAnytype: 1; /// Let the user write __unknown_anytype. + unsigned DebuggerSupport : 1; /// Do things that only make sense when + /// supporting a debugger unsigned SpellChecking : 1; // Whether to perform spell-checking for error // recovery. @@ -130,6 +132,10 @@ public: unsigned DefaultFPContract : 1; // Default setting for FP_CONTRACT // FIXME: This is just a temporary option, for testing purposes. unsigned NoBitFieldTypeAlign : 1; + unsigned ObjCAutoRefCount : 1; // Objective C automated reference counting + unsigned ObjCRuntimeHasWeak : 1; // The ARC runtime supports __weak + unsigned ObjCInferRelatedReturnType : 1; // Infer Objective-C related return + // types unsigned FakeAddressSpaceMap : 1; // Use a fake address space map, for // testing languages such as OpenCL. @@ -172,10 +178,13 @@ public: Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0; GNUMode = GNUKeywords = ImplicitInt = Digraphs = 0; HexFloats = 0; + ObjCAutoRefCount = 0; + ObjCRuntimeHasWeak = 0; + ObjCInferRelatedReturnType = 0; GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0; AppleKext = 0; ObjCDefaultSynthProperties = 0; - ObjCInferRelatedResultType = 0; + ObjCInferRelatedResultType = 1; NoConstantCFStrings = 0; InlineVisibilityHidden = 0; C99 = C1X = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0; CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0; @@ -234,7 +243,7 @@ public: FakeAddressSpaceMap = 0; MRTD = 0; DelayedTemplateParsing = 0; - ParseUnknownAnytype = 0; + ParseUnknownAnytype = DebuggerSupport = 0; } GCMode getGCMode() const { return (GCMode) GC; } diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index df5074c..6301f31 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -36,6 +36,7 @@ class SourceManager; class FileManager; class FileEntry; class LineTableInfo; +class LangOptions; /// SrcMgr - Public enums and private classes that are part of the /// SourceManager implementation. @@ -89,7 +90,7 @@ namespace SrcMgr { /// getBuffer - Returns the memory buffer for the associated content. /// - /// \param Diag Object through which diagnostics will be emitted it the + /// \param Diag Object through which diagnostics will be emitted if the /// buffer cannot be retrieved. /// /// \param Loc If specified, is the location that invalid file diagnostics @@ -238,8 +239,11 @@ namespace SrcMgr { /// InstantiationLocStart/InstantiationLocEnd - In a macro expansion, these /// indicate the start and end of the instantiation. In object-like macros, /// these will be the same. In a function-like macro instantiation, the - /// start will be the identifier and the end will be the ')'. + /// start will be the identifier and the end will be the ')'. Finally, in + /// macro-argument instantitions, the end will be 'SourceLocation()', an + /// invalid location. unsigned InstantiationLocStart, InstantiationLocEnd; + public: SourceLocation getSpellingLoc() const { return SourceLocation::getFromRawEncoding(SpellingLoc); @@ -248,7 +252,9 @@ namespace SrcMgr { return SourceLocation::getFromRawEncoding(InstantiationLocStart); } SourceLocation getInstantiationLocEnd() const { - return SourceLocation::getFromRawEncoding(InstantiationLocEnd); + SourceLocation EndLoc = + SourceLocation::getFromRawEncoding(InstantiationLocEnd); + return EndLoc.isInvalid() ? getInstantiationLocStart() : EndLoc; } std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const { @@ -256,19 +262,52 @@ namespace SrcMgr { getInstantiationLocEnd()); } - /// get - Return a InstantiationInfo for an expansion. IL specifies - /// the instantiation location (where the macro is expanded), and SL - /// specifies the spelling location (where the characters from the token - /// come from). IL and PL can both refer to normal File SLocs or + bool isMacroArgInstantiation() const { + // Note that this needs to return false for default constructed objects. + return getInstantiationLocStart().isValid() && + SourceLocation::getFromRawEncoding(InstantiationLocEnd).isInvalid(); + } + + /// create - Return a InstantiationInfo for an expansion. ILStart and + /// ILEnd specify the instantiation range (where the macro is expanded), + /// and SL specifies the spelling location (where the characters from the + /// token come from). All three can refer to normal File SLocs or /// instantiation locations. - static InstantiationInfo get(SourceLocation ILStart, SourceLocation ILEnd, - SourceLocation SL) { + static InstantiationInfo create(SourceLocation SL, + SourceLocation ILStart, + SourceLocation ILEnd) { InstantiationInfo X; X.SpellingLoc = SL.getRawEncoding(); X.InstantiationLocStart = ILStart.getRawEncoding(); X.InstantiationLocEnd = ILEnd.getRawEncoding(); return X; } + + /// createForMacroArg - Return a special InstantiationInfo for the + /// expansion of a macro argument into a function-like macro's body. IL + /// specifies the instantiation location (where the macro is expanded). + /// This doesn't need to be a range because a macro is always instantiated + /// at a macro parameter reference, and macro parameters are always exactly + /// one token. SL specifies the spelling location (where the characters + /// from the token come from). IL and SL can both refer to normal File + /// SLocs or instantiation locations. + /// + /// Given the code: + /// \code + /// #define F(x) f(x) + /// F(42); + /// \endcode + /// + /// When expanding '\c F(42)', the '\c x' would call this with an SL + /// pointing at '\c 42' anad an IL pointing at its location in the + /// definition of '\c F'. + static InstantiationInfo createForMacroArg(SourceLocation SL, + SourceLocation IL) { + // We store an intentionally invalid source location for the end of the + // instantiation range to mark that this is a macro argument instantation + // rather than a normal one. + return create(SL, IL, SourceLocation()); + } }; /// SLocEntry - This is a discriminated union of FileInfo and @@ -500,8 +539,8 @@ public: //===--------------------------------------------------------------------===// /// createFileID - Create a new FileID that represents the specified file - /// being #included from the specified IncludePosition. This returns 0 on - /// error and translates NULL into standard input. + /// being #included from the specified IncludePosition. This translates NULL + /// into standard input. /// PreallocateID should be non-zero to specify which pre-allocated, /// lazily computed source location is being filled in by this operation. FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, @@ -532,9 +571,17 @@ public: return MainFileID; } + /// createMacroArgInstantiationLoc - Return a new SourceLocation that encodes + /// the fact that a token from SpellingLoc should actually be referenced from + /// InstantiationLoc, and that it represents the instantiation of a macro + /// argument into the function-like macro body. + SourceLocation createMacroArgInstantiationLoc(SourceLocation Loc, + SourceLocation InstantiationLoc, + unsigned TokLength); + /// createInstantiationLoc - Return a new SourceLocation that encodes the fact - /// that a token at Loc should actually be referenced from InstantiationLoc. - /// TokLength is the length of the token being instantiated. + /// that a token from SpellingLoc should actually be referenced from + /// InstantiationLoc. SourceLocation createInstantiationLoc(SourceLocation Loc, SourceLocation InstantiationLocStart, SourceLocation InstantiationLocEnd, @@ -721,7 +768,7 @@ public: if (Loc.isFileID()) return std::make_pair(FID, Offset); - return getDecomposedInstantiationLocSlowCase(E, Offset); + return getDecomposedInstantiationLocSlowCase(E); } /// getDecomposedSpellingLoc - Decompose the specified location into a raw @@ -745,6 +792,12 @@ public: return getDecomposedLoc(SpellingLoc).second; } + /// isMacroArgInstantiation - This method tests whether the given source + /// location represents a macro argument's instantiation into the + /// function-like macro definition. Such source locations only appear inside + /// of the instantiation locations representing where a particular + /// function-like macro was expanded. + bool isMacroArgInstantiation(SourceLocation Loc) const; //===--------------------------------------------------------------------===// // Queries about the code at a SourceLocation. @@ -831,13 +884,38 @@ public: return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem; } - /// \brief Returns true if the given MacroID location points at the first - /// token of the macro instantiation. - bool isAtStartOfMacroInstantiation(SourceLocation Loc) const; + /// \brief Given a specific chunk of a FileID (FileID with offset+length), + /// returns true if \arg Loc is inside that chunk and sets relative offset + /// (offset of \arg Loc from beginning of chunk) to \arg relativeOffset. + bool isInFileID(SourceLocation Loc, + FileID FID, unsigned offset, unsigned length, + unsigned *relativeOffset = 0) const { + assert(!FID.isInvalid()); + if (Loc.isInvalid()) + return false; + + unsigned start = getSLocEntry(FID).getOffset() + offset; + unsigned end = start + length; + +#ifndef NDEBUG + // Make sure offset/length describe a chunk inside the given FileID. + unsigned NextOffset; + if (FID.ID+1 == SLocEntryTable.size()) + NextOffset = getNextOffset(); + else + NextOffset = getSLocEntry(FID.ID+1).getOffset(); + assert(start < NextOffset); + assert(end < NextOffset); +#endif - /// \brief Returns true if the given MacroID location points at the last - /// token of the macro instantiation. - bool isAtEndOfMacroInstantiation(SourceLocation Loc) const; + if (Loc.getOffset() >= start && Loc.getOffset() < end) { + if (relativeOffset) + *relativeOffset = Loc.getOffset() - start; + return true; + } + + return false; + } //===--------------------------------------------------------------------===// // Line Table Manipulation Routines @@ -845,7 +923,7 @@ public: /// getLineTableFilenameID - Return the uniqued ID for the specified filename. /// - unsigned getLineTableFilenameID(const char *Ptr, unsigned Len); + unsigned getLineTableFilenameID(llvm::StringRef Str); /// AddLineNote - Add a line note to the line table for the FileID and offset /// specified by Loc. If FilenameID is -1, it is considered to be @@ -899,6 +977,19 @@ public: /// \returns true if LHS source location comes before RHS, false otherwise. bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const; + /// \brief Determines the order of 2 source locations in the "source location + /// address space". + static bool isBeforeInSourceLocationOffset(SourceLocation LHS, + SourceLocation RHS) { + return isBeforeInSourceLocationOffset(LHS, RHS.getOffset()); + } + + /// \brief Determines the order of a source location and a source location + /// offset in the "source location address space". + static bool isBeforeInSourceLocationOffset(SourceLocation LHS, unsigned RHS) { + return LHS.getOffset() < RHS; + } + // Iterators over FileInfos. typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> ::const_iterator fileinfo_iterator; @@ -952,6 +1043,14 @@ public: private: const llvm::MemoryBuffer *getFakeBufferForRecovery() const; + /// createInstantiationLoc - Implements the common elements of storing an + /// instantiation info struct into the SLocEntry table and producing a source + /// location that refers to it. + SourceLocation createInstantiationLocImpl(const SrcMgr::InstantiationInfo &II, + unsigned TokLength, + unsigned PreallocatedID = 0, + unsigned Offset = 0); + /// isOffsetInFileID - Return true if the specified FileID contains the /// specified SourceLocation offset. This is a very hot method. inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const { @@ -989,8 +1088,7 @@ private: SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const; std::pair<FileID, unsigned> - getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, - unsigned Offset) const; + getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E) const; std::pair<FileID, unsigned> getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, unsigned Offset) const; diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h index 258989c..3f5d1a3 100644 --- a/include/clang/Basic/SourceManagerInternals.h +++ b/include/clang/Basic/SourceManagerInternals.h @@ -97,7 +97,7 @@ public: ~LineTableInfo() {} - unsigned getLineTableFilenameID(const char *Ptr, unsigned Len); + unsigned getLineTableFilenameID(llvm::StringRef Str); const char *getFilename(unsigned ID) const { assert(ID < FilenamesByID.size() && "Invalid FilenameID"); return FilenamesByID[ID]->getKeyData(); diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h index d21bda7..cfce0cc 100644 --- a/include/clang/Basic/Specifiers.h +++ b/include/clang/Basic/Specifiers.h @@ -83,7 +83,7 @@ namespace clang { /// ExprValueKind - The categorization of expression values, /// currently following the C++0x scheme. enum ExprValueKind { - /// An r-value expression (a gr-value in the C++0x taxonomy) + /// An r-value expression (a pr-value in the C++0x taxonomy) /// produces a temporary value. VK_RValue, diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 03f4cc3..73996e4 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -37,6 +37,7 @@ def ObjCAtFinallyStmt : Stmt; def ObjCAtThrowStmt : Stmt; def ObjCAtSynchronizedStmt : Stmt; def ObjCForCollectionStmt : Stmt; +def ObjCAutoreleasePoolStmt : Stmt; // C++ statments def CXXCatchStmt : Stmt; @@ -119,7 +120,9 @@ def UnresolvedMemberExpr : DStmt<OverloadExpr>; def CXXNoexceptExpr : DStmt<Expr>; def PackExpansionExpr : DStmt<Expr>; def SizeOfPackExpr : DStmt<Expr>; +def SubstNonTypeTemplateParmExpr : DStmt<Expr>; def SubstNonTypeTemplateParmPackExpr : DStmt<Expr>; +def MaterializeTemporaryExpr : DStmt<Expr>; // Obj-C Expressions. def ObjCStringLiteral : DStmt<Expr>; @@ -130,6 +133,10 @@ def ObjCProtocolExpr : DStmt<Expr>; def ObjCIvarRefExpr : DStmt<Expr>; def ObjCPropertyRefExpr : DStmt<Expr>; def ObjCIsaExpr : DStmt<Expr>; +def ObjCIndirectCopyRestoreExpr : DStmt<Expr>; + +// Obj-C ARC Expressions. +def ObjCBridgedCastExpr : DStmt<ExplicitCastExpr>; // CUDA Expressions. def CUDAKernelCallExpr : DStmt<CallExpr>; diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 76006d4..4559cf2 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -240,6 +240,14 @@ public: return getTypeWidth(IntMaxType); } + /// getRegisterWidth - Return the "preferred" register width on this target. + uint64_t 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; + } + /// getUserLabelPrefix - This returns the default value of the /// __USER_LABEL_PREFIX__ macro, which is the prefix given to user symbols by /// default. On most platforms this is "_", but it is "" on some, and "." on @@ -295,6 +303,11 @@ public: /// __builtin_va_list, which is target-specific. virtual const char *getVAListDeclaration() const = 0; + /// isValidClobber - Returns whether the passed in string is + /// a valid clobber in an inline asm statement. This is used by + /// Sema. + bool isValidClobber(llvm::StringRef Name) const; + /// isValidGCCRegisterName - Returns whether the passed in string /// is a valid register name according to GCC. This is used by Sema for /// inline asm statements. @@ -396,6 +409,11 @@ public: const char * const Register; }; + struct AddlRegName { + const char * const Names[5]; + const unsigned RegNum; + }; + virtual bool useGlobalsForAutomaticVariables() const { return false; } /// getCFStringSection - Return the section to use for CFString @@ -511,6 +529,7 @@ public: // getRegParmMax - Returns maximal number of args passed in registers. unsigned getRegParmMax() const { + assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle"); return RegParmMax; } @@ -566,6 +585,11 @@ protected: unsigned &NumNames) const = 0; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, unsigned &NumAliases) const = 0; + virtual void getGCCAddlRegNames(const AddlRegName *&Addl, + unsigned &NumAddl) const { + Addl = 0; + NumAddl = 0; + } virtual bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const= 0; }; diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index dfba7ee..86172b8 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -422,6 +422,12 @@ KEYWORD(__pascal , KEYALL) KEYWORD(__vector , KEYALTIVEC) KEYWORD(__pixel , KEYALTIVEC) +// Objective-C ARC keywords. +KEYWORD(__bridge , KEYARC) +KEYWORD(__bridge_transfer , KEYARC) +KEYWORD(__bridge_retained , KEYARC) +KEYWORD(__bridge_retain , KEYARC) + // Alternate spelling for various tokens. There are GCC extensions in all // languages, but should not be disabled in strict conformance mode. ALIAS("__alignof__" , __alignof , KEYALL) @@ -507,6 +513,7 @@ OBJC1_AT_KEYWORD(try) OBJC1_AT_KEYWORD(catch) OBJC1_AT_KEYWORD(finally) OBJC1_AT_KEYWORD(synchronized) +OBJC1_AT_KEYWORD(autoreleasepool) OBJC2_AT_KEYWORD(property) OBJC2_AT_KEYWORD(package) diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td index b3da122..71a0aa2 100644 --- a/include/clang/Basic/arm_neon.td +++ b/include/clang/Basic/arm_neon.td @@ -182,7 +182,7 @@ def VMAX : SInst<"vmax", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">; def VMIN : SInst<"vmin", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">; //////////////////////////////////////////////////////////////////////////////// -// E.3.7 Pairdise Addition +// E.3.7 Pairwise Addition def VPADD : IInst<"vpadd", "ddd", "csiUcUsUif">; def VPADDL : SInst<"vpaddl", "nd", "csiUcUsUiQcQsQiQUcQUsQUi">; def VPADAL : SInst<"vpadal", "nnd", "csiUcUsUiQcQsQiQUcQUsQUi">; @@ -352,7 +352,7 @@ def VEXT : WInst<"vext", "dddi", "cUcPcsUsPsiUilUlfQcQUcQPcQsQUsQPsQiQUiQlQUlQf">; //////////////////////////////////////////////////////////////////////////////// -// E.3.27 Reverse vector elements (sdap endianness) +// E.3.27 Reverse vector elements def VREV64 : Inst<"vrev64", "dd", "csiUcUsUiPcPsfQcQsQiQUcQUsQUiQPcQPsQf", OP_REV64>; def VREV32 : Inst<"vrev32", "dd", "csUcUsPcPsQcQsQUcQUsQPcQPs", OP_REV32>; diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h index abcef81..9636d6e 100644 --- a/include/clang/CodeGen/BackendUtil.h +++ b/include/clang/CodeGen/BackendUtil.h @@ -19,6 +19,7 @@ namespace clang { class Diagnostic; class CodeGenOptions; class TargetOptions; + class LangOptions; enum BackendAction { Backend_EmitAssembly, ///< Emit native assembly files @@ -30,7 +31,8 @@ namespace clang { }; void EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts, - const TargetOptions &TOpts, llvm::Module *M, + const TargetOptions &TOpts, const LangOptions &LOpts, + llvm::Module *M, BackendAction Action, llvm::raw_ostream *OS); } diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 14d8f67..d8e9e3d 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -143,6 +143,8 @@ def femit_coverage_data: Flag<"-femit-coverage-data">, def coverage_file : Separate<"-coverage-file">, HelpText<"Emit coverage data to this filename. The extension will be replaced.">; def coverage_file_EQ : Joined<"-coverage-file=">, Alias<coverage_file>; +def fuse_register_sized_bitfield_access: Flag<"-fuse-register-sized-bitfield-access">, + HelpText<"Use register sized accesses to bit-fields, when possible.">; def relaxed_aliasing : Flag<"-relaxed-aliasing">, HelpText<"Turn off Type Based Alias Analysis">; def masm_verbose : Flag<"-masm-verbose">, @@ -157,6 +159,8 @@ def mfloat_abi : Separate<"-mfloat-abi">, HelpText<"The float ABI to use">; def mlimit_float_precision : Separate<"-mlimit-float-precision">, HelpText<"Limit float precision to the given value">; +def mno_exec_stack : Flag<"-mnoexecstack">, + HelpText<"Mark the file as not needing an executable stack">; def mno_zero_initialized_in_bss : Flag<"-mno-zero-initialized-in-bss">, HelpText<"Do not put zero initialized data in the BSS">; def momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">, @@ -204,6 +208,7 @@ def MQ : Separate<"-MQ">, HelpText<"Specify target to quote for dependency">; def MT : Separate<"-MT">, HelpText<"Specify target for dependency">; def MP : Flag<"-MP">, HelpText<"Create phony target for each dependency (other than main file)">; +def MG : Flag<"-MG">, HelpText<"Add missing headers to dependency list">; //===----------------------------------------------------------------------===// // Diagnostic Options @@ -259,7 +264,7 @@ def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">, def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">, HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">; def fmacro_backtrace_limit : Separate<"-fmacro-backtrace-limit">, MetaVarName<"<N>">, - HelpText<"Set the maximum number of entries to print in a macro instantiation backtrace (0 = no limit).">; + HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">; def ftemplate_backtrace_limit : Separate<"-ftemplate-backtrace-limit">, MetaVarName<"<N>">, HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">; def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">, @@ -352,8 +357,6 @@ 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 boostcon : Flag<"-boostcon">, - HelpText<"BoostCon workshop mode">; def print_decl_contexts : Flag<"-print-decl-contexts">, HelpText<"Print DeclContexts and their Decls">; def emit_pth : Flag<"-emit-pth">, @@ -383,6 +386,15 @@ def create_module : Flag<"-create-module">, HelpText<"Create a module definition file">; } +def arcmt_check : Flag<"-arcmt-check">, + HelpText<"Check for ARC migration issues that need manual handling">; +def arcmt_modify : Flag<"-arcmt-modify">, + HelpText<"Apply modifications to files to conform to ARC">; +def arcmt_migrate : Flag<"-arcmt-migrate">, + HelpText<"Apply modifications and produces temporary files that conform to ARC">; +def arcmt_migrate_directory : Separate<"-arcmt-migrate-directory">, + HelpText<"Directory for temporary files produced during ARC migration">; + def import_module : Separate<"-import-module">, HelpText<"Import a module definition file">; @@ -452,6 +464,8 @@ def fhidden_weak_vtables : Flag<"-fhidden-weak-vtables">, HelpText<"Generate weak vtables and RTTI with hidden visibility">; def std_EQ : Joined<"-std=">, HelpText<"Language standard to compile for">; +def stdlib_EQ : Joined<"-stdlib=">, + HelpText<"C++ standard library to use">; def fmath_errno : Flag<"-fmath-errno">, HelpText<"Require math functions to indicate errors by setting errno">; def fms_extensions : Flag<"-fms-extensions">, @@ -479,6 +493,18 @@ def fconstant_string_class : Separate<"-fconstant-string-class">, HelpText<"Specify the class to use for constant Objective-C string objects.">; def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">, HelpText<"Enable creation of CodeFoundation-type constant strings">; +def fobjc_arc : Flag<"-fobjc-arc">, + HelpText<"Synthesize retain and release calls for Objective-C pointers">; +def fobjc_arc_cxxlib_EQ : Joined<"-fobjc-arc-cxxlib=">, + HelpText<"Objective-C++ Automatic Reference Counting standard library kind">; +def fobjc_arc_exceptions : Flag<"-fobjc-arc-exceptions">, + HelpText<"Use EH-safe code when synthesizing retains and releases in -fobjc-arc">; +def fobjc_runtime_has_arc : Flag<"-fobjc-runtime-has-arc">, + HelpText<"The target Objective-C runtime provides ARC entrypoints">; +def fobjc_runtime_has_weak : Flag<"-fobjc-runtime-has-weak">, + HelpText<"The target Objective-C runtime supports ARC weak operations">; +def fobjc_runtime_has_terminate : Flag<"-fobjc-runtime-has-terminate">, + HelpText<"The target Objective-C runtime provides an objc_terminate entrypoint">; def fobjc_gc : Flag<"-fobjc-gc">, HelpText<"Enable Objective-C garbage collection">; def fobjc_gc_only : Flag<"-fobjc-gc-only">, @@ -493,8 +519,10 @@ def print_ivar_layout : Flag<"-print-ivar-layout">, HelpText<"Enable Objective-C Ivar layout bitmap print trace">; def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, HelpText<"enable objective-c's nonfragile abi">; -def fobjc_infer_related_result_type : Flag<"-fobjc-infer-related-result-type">, - HelpText<"infer Objective-C related result type based on method family">; +def fno_objc_infer_related_result_type : Flag< + "-fno-objc-infer-related-result-type">, + HelpText< + "do not infer Objective-C related result type based on method family">; def ftrapv : Flag<"-ftrapv">, HelpText<"Trap on integer overflow">; def ftrapv_handler : Separate<"-ftrapv-handler">, @@ -554,6 +582,8 @@ def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">, "translation unit ">; 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">, + HelpText<"Enable special debugger support behavior">; def fdeprecated_macro : Flag<"-fdeprecated-macro">, HelpText<"Defines the __DEPRECATED macro">; def fno_deprecated_macro : Flag<"-fno-deprecated-macro">, diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h index 22d6b4e..2db712d 100644 --- a/include/clang/Driver/Compilation.h +++ b/include/clang/Driver/Compilation.h @@ -14,7 +14,6 @@ #include "clang/Driver/Util.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" namespace llvm { class raw_ostream; diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 5a7d830..b695166 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -357,6 +357,8 @@ public: bool ShouldUseClangCompiler(const Compilation &C, const JobAction &JA, const llvm::Triple &ArchName) const; + bool IsUsingLTO(const ArgList &Args) const; + /// @} /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and diff --git a/include/clang/Driver/ObjCRuntime.h b/include/clang/Driver/ObjCRuntime.h new file mode 100644 index 0000000..5516460 --- /dev/null +++ b/include/clang/Driver/ObjCRuntime.h @@ -0,0 +1,46 @@ +//===--- ObjCRuntime.h - Objective C runtime features -----------*- 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_OBJCRUNTIME_H_ +#define CLANG_DRIVER_OBJCRUNTIME_H_ + +namespace clang { +namespace driver { + +class ObjCRuntime { +public: + enum Kind { GNU, NeXT }; +private: + unsigned RuntimeKind : 1; +public: + void setKind(Kind k) { RuntimeKind = k; } + Kind getKind() const { return static_cast<Kind>(RuntimeKind); } + + /// True if the runtime provides native ARC entrypoints. ARC may + /// still be usable without this if the tool-chain provides a + /// statically-linked runtime support library. + unsigned HasARC : 1; + + /// True if the runtime supports ARC zeroing __weak. + unsigned HasWeak : 1; + + /// True if the runtime provides the following entrypoint: + /// void objc_terminate(void); + /// If available, this will be called instead of abort() when an + /// exception is thrown out of an EH cleanup. + unsigned HasTerminate : 1; + + ObjCRuntime() : RuntimeKind(NeXT), HasARC(false), HasWeak(false), + HasTerminate(false) {} +}; + +} +} + +#endif diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h index 9625465..9dfa461 100644 --- a/include/clang/Driver/Option.h +++ b/include/clang/Driver/Option.h @@ -11,6 +11,7 @@ #define CLANG_DRIVER_OPTION_H_ #include "clang/Driver/OptSpecifier.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" using llvm::isa; using llvm::cast; @@ -64,7 +65,7 @@ namespace driver { OptSpecifier ID; /// The option name. - const char *Name; + llvm::StringRef Name; /// Group this option is a member of, if any. const OptionGroup *Group; @@ -103,7 +104,7 @@ namespace driver { unsigned getID() const { return ID.getID(); } OptionClass getKind() const { return Kind; } - const char *getName() const { return Name; } + llvm::StringRef getName() const { return Name; } const OptionGroup *getGroup() const { return Group; } const Option *getAlias() const { return Alias; } @@ -143,7 +144,7 @@ namespace driver { /// getRenderName - Return the name to use when rendering this /// option. - const char *getRenderName() const { + llvm::StringRef getRenderName() const { return getUnaliasedOption()->getName(); } diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 7203976..d548276 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -112,6 +112,17 @@ def ccc_print_phases : Flag<"-ccc-print-phases">, CCCDebugOpt, def ccc_print_bindings : Flag<"-ccc-print-bindings">, CCCDebugOpt, HelpText<"Show bindings of tools to actions">; +def ccc_arcmt_check : Flag<"-ccc-arcmt-check">, CCCDriverOpt, + HelpText<"Check for ARC migration issues that need manual handling">; +def ccc_arcmt_modify : Flag<"-ccc-arcmt-modify">, CCCDriverOpt, + HelpText<"Apply modifications to files to conform to ARC">; +def ccc_arrmt_check : Flag<"-ccc-arrmt-check">, Alias<ccc_arcmt_check>; +def ccc_arrmt_modify : Flag<"-ccc-arrmt-modify">, Alias<ccc_arcmt_modify>; +def ccc_arcmt_migrate : Separate<"-ccc-arcmt-migrate">, CCCDriverOpt, + HelpText<"Apply modifications and produces temporary files that conform to ARC">; +def ccc_arcmt_migrate_EQ : Joined<"-ccc-arcmt-migrate=">, CCCDriverOpt, + Alias<ccc_arcmt_migrate>; + // Make sure all other -ccc- options are rejected. def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>; @@ -382,6 +393,10 @@ def fno_verbose_asm : Flag<"-fno-verbose-asm">, Group<f_Group>; def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>; def fno_wrapv : Flag<"-fno-wrapv">, Group<f_Group>; def fno_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>; +def fobjc_arc : Flag<"-fobjc-arc">, Group<f_Group>; +def fno_objc_arc : Flag<"-fno-objc-arc">, Group<f_Group>; +def fobjc_arc_exceptions : Flag<"-fobjc-arc-exceptions">, Group<f_Group>; +def fno_objc_arc_exceptions : Flag<"-fno-objc-arc-exceptions">, Group<f_Group>; def fobjc_atdefs : Flag<"-fobjc-atdefs">, Group<clang_ignored_f_Group>; def fobjc_call_cxx_cdtors : Flag<"-fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>; def fobjc_default_synthesize_properties : @@ -409,6 +424,7 @@ def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>; def fopenmp : Flag<"-fopenmp">, Group<f_Group>; def force__cpusubtype__ALL : Flag<"-force_cpusubtype_ALL">; def force__flat__namespace : Flag<"-force_flat_namespace">; +def force__load : Separate<"-force_load">; def foutput_class_dir_EQ : Joined<"-foutput-class-dir=">, Group<f_Group>; def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>; def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>; @@ -803,8 +819,8 @@ def _specs : Separate<"--specs">, Alias<specs_EQ>; def _static : Flag<"--static">, Alias<static>; def _std_EQ : Joined<"--std=">, Alias<std_EQ>; def _std : Separate<"--std">, Alias<std_EQ>; -def _stdlib_EQ : Joined<"--stdlib=">, Alias<std_EQ>; -def _stdlib : Separate<"--stdlib">, Alias<std_EQ>; +def _stdlib_EQ : Joined<"--stdlib=">, Alias<stdlib_EQ>; +def _stdlib : Separate<"--stdlib">, Alias<stdlib_EQ>; def _sysroot_EQ : Joined<"--sysroot=">; def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>; def _target_help : Flag<"--target-help">; diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 626d54c..4836d3f 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -26,6 +26,7 @@ namespace driver { class HostInfo; class InputArgList; class JobAction; + class ObjCRuntime; class Tool; /// ToolChain - Access to tools for a single platform. @@ -177,6 +178,12 @@ public: /// Clang. virtual std::string ComputeEffectiveClangTriple(const ArgList &Args) const; + /// configureObjCRuntime - Configure the known properties of the + /// Objective-C runtime for this platform. + /// + /// FIXME: this doesn't really belong here. + virtual void configureObjCRuntime(ObjCRuntime &runtime) const; + // GetCXXStdlibType - Determine the C++ standard library type to use with the // given compilation arguments. virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const; @@ -184,7 +191,8 @@ public: /// 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 &Args, - ArgStringList &CmdArgs) const; + ArgStringList &CmdArgs, + bool ObjCXXAutoRefCount) const; /// AddCXXStdlibLibArgs - Add the system specific linker arguments to use /// for the given C++ standard library type. diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 339297e..58a60a1 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -249,9 +249,9 @@ private: /// \brief Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults; - /// \brief Whether we want to include nested macro instantiations in the + /// \brief Whether we want to include nested macro expansions in the /// detailed preprocessing record. - bool NestedMacroInstantiations; + bool NestedMacroExpansions; static void ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags, const char **ArgBegin, const char **ArgEnd, @@ -363,7 +363,7 @@ private: unsigned MaxLines, bool &CreatedBuffer); llvm::MemoryBuffer *getMainBufferWithPrecompiledPreamble( - CompilerInvocation PreambleInvocation, + const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild = true, unsigned MaxLines = 0); void RealizeTopLevelDeclsFromPreamble(); @@ -612,7 +612,7 @@ public: bool PrecompilePreamble = false, bool CompleteTranslationUnit = true, bool CacheCodeCompletionResults = false, - bool NestedMacroInstantiations = true); + bool NestedMacroExpansions = true); /// LoadFromCommandLine - Create an ASTUnit from a vector of command line /// arguments, which must specify exactly one source file. @@ -642,7 +642,7 @@ public: bool CacheCodeCompletionResults = false, bool CXXPrecompilePreamble = false, bool CXXChainedPCH = false, - bool NestedMacroInstantiations = true); + bool NestedMacroExpansions = true); /// \brief Reparse the source files using the same command-line options that /// were originally used to produce this translation unit. @@ -680,8 +680,8 @@ public: /// \brief Save this translation unit to a file with the given name. /// - /// \returns True if an error occurred, false otherwise. - bool Save(llvm::StringRef File); + /// \returns An indication of whether the save was successful or not. + CXSaveError Save(llvm::StringRef File); /// \brief Serialize this translation unit with the given output stream. /// diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index 1c686c7..5d040b4 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -36,6 +36,7 @@ public: }; unsigned AsmVerbose : 1; /// -dA, -fverbose-asm. + unsigned ObjCAutoRefCountExceptions : 1; /// Whether ARC should be EH-safe. unsigned CXAAtExit : 1; /// Use __cxa_atexit for calling destructors. unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker /// aliases to base ctors when possible. @@ -69,11 +70,14 @@ public: unsigned MergeAllConstants : 1; /// Merge identical constants. unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled. unsigned NoDwarf2CFIAsm : 1; /// Set when -fno-dwarf2-cfi-asm is enabled. + unsigned NoExecStack : 1; /// Set when -Wa,--noexecstack is enabled. unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled. unsigned NoInfsFPMath : 1; /// Assume FP arguments, results not +-Inf. unsigned NoNaNsFPMath : 1; /// Assume FP arguments, results not NaN. unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use. + unsigned ObjCRuntimeHasARC : 1; /// The target runtime supports ARC natively + unsigned ObjCRuntimeHasTerminate : 1; /// The ObjC runtime has objc_terminate unsigned OmitLeafFramePointer : 1; /// Set when -momit-leaf-frame-pointer is /// enabled. unsigned OptimizationLevel : 3; /// The -O[0-4] option specified. @@ -89,6 +93,11 @@ public: unsigned UnrollLoops : 1; /// Control whether loops are unrolled. unsigned UnsafeFPMath : 1; /// Allow unsafe floating point optzns. unsigned UnwindTables : 1; /// Emit unwind tables. + + /// Attempt to use register sized accesses to bit-fields in structures, when + /// possible. + unsigned UseRegisterSizedBitfieldAccess : 1; + unsigned VerifyModule : 1; /// Control whether the module should be run /// through the LLVM Verifier. @@ -159,7 +168,10 @@ public: NoNaNsFPMath = 0; NoZeroInitializedInBSS = 0; NumRegisterParameters = 0; + ObjCAutoRefCountExceptions = 0; ObjCDispatchMethod = Legacy; + ObjCRuntimeHasARC = 0; + ObjCRuntimeHasTerminate = 0; OmitLeafFramePointer = 0; OptimizationLevel = 0; OptimizeSize = 0; @@ -173,6 +185,7 @@ public: UnrollLoops = 0; UnsafeFPMath = 0; UnwindTables = 0; + UseRegisterSizedBitfieldAccess = 0; VerifyModule = 1; Inlining = NoInlining; diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h index 35aa6c6..1e22c22 100644 --- a/include/clang/Frontend/DependencyOutputOptions.h +++ b/include/clang/Frontend/DependencyOutputOptions.h @@ -24,6 +24,7 @@ public: unsigned UsePhonyTargets : 1; ///< Include phony targets for each /// dependency, which can avoid some 'make' /// problems. + unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list /// The file to write dependency output to. std::string OutputFile; @@ -43,6 +44,7 @@ public: IncludeSystemHeaders = 0; ShowHeaderIncludes = 0; UsePhonyTargets = 0; + AddMissingHeaderDeps = 0; } }; diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h index 56093c3..5ae8eb3 100644 --- a/include/clang/Frontend/DiagnosticOptions.h +++ b/include/clang/Frontend/DiagnosticOptions.h @@ -49,8 +49,7 @@ public: /// input source file. unsigned ErrorLimit; /// Limit # errors emitted. - unsigned MacroBacktraceLimit; /// Limit depth of macro instantiation - /// backtrace. + unsigned MacroBacktraceLimit; /// Limit depth of macro expansion backtrace. unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace. /// The distance between tab stops. diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h index ee0863a..f335475 100644 --- a/include/clang/Frontend/FrontendAction.h +++ b/include/clang/Frontend/FrontendAction.h @@ -51,6 +51,7 @@ class FrontendAction { llvm::OwningPtr<ASTUnit> CurrentASTUnit; CompilerInstance *Instance; friend class ASTMergeAction; + friend class WrapperFrontendAction; private: ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI, @@ -77,6 +78,14 @@ protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) = 0; + /// \brief Callback before starting processing a single input, giving the + /// opportunity to modify the CompilerInvocation or do some other action + /// before BeginSourceFileAction is called. + /// + /// \return True on success; on failure \see BeginSourceFileAction() and + /// ExecutionAction() and EndSourceFileAction() will not be called. + virtual bool BeginInvocation(CompilerInstance &CI) { return true; } + /// BeginSourceFileAction - Callback at the start of processing a single /// input. /// @@ -253,6 +262,36 @@ public: virtual bool usesPreprocessorOnly() const { return true; } }; +/// WrapperFrontendAction - A frontend action which simply wraps some other +/// runtime specified frontend action. Deriving from this class allows an +/// action to inject custom logic around some existing action's behavior. It +/// implements every virtual method in the FrontendAction interface by +/// forwarding to the wrapped action. +class WrapperFrontendAction : public FrontendAction { + llvm::OwningPtr<FrontendAction> WrappedAction; + +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); + virtual bool BeginInvocation(CompilerInstance &CI); + virtual bool BeginSourceFileAction(CompilerInstance &CI, + llvm::StringRef Filename); + virtual void ExecuteAction(); + virtual void EndSourceFileAction(); + +public: + /// Construct a WrapperFrontendAction from an existing action, taking + /// ownership of it. + WrapperFrontendAction(FrontendAction *WrappedAction); + + virtual bool usesPreprocessorOnly() const; + virtual bool usesCompleteTranslationUnit(); + virtual bool hasPCHSupport() const; + virtual bool hasASTFileSupport() const; + virtual bool hasIRSupport() const; + virtual bool hasCodeCompletionSupport() const; +}; + } // end namespace clang #endif diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h index 4e67449..b409ad1 100644 --- a/include/clang/Frontend/FrontendActions.h +++ b/include/clang/Frontend/FrontendActions.h @@ -97,12 +97,6 @@ public: virtual bool hasCodeCompletionSupport() const { return true; } }; -class BoostConAction : public SyntaxOnlyAction { -protected: - virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef InFile); -}; - /** * \brief Frontend action adaptor that merges ASTs together. * diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 02f6f86..225a955 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -24,7 +24,6 @@ namespace frontend { ASTDumpXML, ///< Parse ASTs and dump them in XML. ASTPrint, ///< Parse ASTs and print them. ASTView, ///< Parse ASTs and view them in Graphviz. - BoostCon, ///< BoostCon mode. CreateModule, ///< Create module definition DumpRawTokens, ///< Dump out raw tokens. DumpTokens, ///< Dump out preprocessed tokens. @@ -77,6 +76,15 @@ public: unsigned FixWhatYouCan : 1; ///< Apply fixes even if there are /// unfixable errors. + enum { + ARCMT_None, + ARCMT_Check, + ARCMT_Modify, + ARCMT_Migrate + } ARCMTAction; + + std::string ARCMTMigrateDir; + /// The input files and their types. std::vector<std::pair<InputKind, std::string> > Inputs; @@ -131,6 +139,7 @@ public: ShowStats = 0; ShowTimers = 0; ShowVersion = 0; + ARCMTAction = ARCMT_None; } /// getInputKindForExtension - Return the appropriate input kind for a file diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h index b0669eb..0347f98 100644 --- a/include/clang/Frontend/HeaderSearchOptions.h +++ b/include/clang/Frontend/HeaderSearchOptions.h @@ -17,10 +17,12 @@ namespace clang { namespace frontend { /// IncludeDirGroup - Identifiers the group a include entry belongs to, which - /// represents its relative positive in the search list. + /// represents its relative positive in the search list. A #include of a "" + /// path starts at the -iquote group, then searches the Angled group, then + /// searches the system group, etc. enum IncludeDirGroup { - Quoted = 0, ///< `#include ""` paths. Thing `gcc -iquote`. - Angled, ///< Paths for both `#include ""` and `#include <>`. (`-I`) + Quoted = 0, ///< '#include ""' paths, added by'gcc -iquote'. + Angled, ///< Paths for '#include <>' added by '-I'. System, ///< Like Angled, but marks system directories. CXXSystem, ///< Like System, but only used for C++. After ///< Like System, but searched after the system directories. @@ -37,15 +39,15 @@ public: unsigned IsUserSupplied : 1; unsigned IsFramework : 1; - /// IsSysRootRelative - This is true if an absolute path should be treated - /// relative to the sysroot, or false if it should always be the absolute + /// IgnoreSysRoot - This is false if an absolute path should be treated + /// relative to the sysroot, or true if it should always be the absolute /// path. - unsigned IsSysRootRelative : 1; + unsigned IgnoreSysRoot : 1; Entry(llvm::StringRef path, frontend::IncludeDirGroup group, - bool isUserSupplied, bool isFramework, bool isSysRootRelative) + bool isUserSupplied, bool isFramework, bool ignoreSysRoot) : Path(path), Group(group), IsUserSupplied(isUserSupplied), - IsFramework(isFramework), IsSysRootRelative(isSysRootRelative) {} + IsFramework(isFramework), IgnoreSysRoot(ignoreSysRoot) {} }; /// If non-empty, the directory to use as a "virtual system root" for include @@ -80,20 +82,23 @@ public: /// Include the system standard C++ library include search directories. unsigned UseStandardCXXIncludes : 1; + /// Use libc++ instead of the default libstdc++. + unsigned UseLibcxx : 1; + /// Whether header search information should be output as for -v. unsigned Verbose : 1; public: HeaderSearchOptions(llvm::StringRef _Sysroot = "/") : Sysroot(_Sysroot), UseBuiltinIncludes(true), - UseStandardIncludes(true), UseStandardCXXIncludes(true), + UseStandardIncludes(true), UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false) {} /// AddPath - Add the \arg Path path to the specified \arg Group list. void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group, - bool IsUserSupplied, bool IsFramework, bool IsSysRootRelative) { + bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot) { UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework, - IsSysRootRelative)); + IgnoreSysRoot)); } }; diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h index e471c5c..2e16c97 100644 --- a/include/clang/Frontend/PreprocessorOptions.h +++ b/include/clang/Frontend/PreprocessorOptions.h @@ -1,4 +1,4 @@ -//===--- PreprocessorOptionms.h ---------------------------------*- C++ -*-===// +//===--- PreprocessorOptions.h ----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -26,6 +26,15 @@ namespace clang { class Preprocessor; class LangOptions; +/// \brief Enumerate the kinds of standard library that +enum ObjCXXARCStandardLibraryKind { + ARCXX_nolib, + /// \brief libc++ + ARCXX_libcxx, + /// \brief libstdc++ + ARCXX_libstdcxx +}; + /// PreprocessorOptions - This class is used for passing the various options /// used in preprocessor initialization to InitializePreprocessor(). class PreprocessorOptions { @@ -39,11 +48,11 @@ public: unsigned DetailedRecord : 1; /// Whether we should maintain a detailed /// record of all macro definitions and - /// instantiations. + /// expansions. /// \brief Whether the detailed preprocessing record includes nested macro - /// instantiations. - unsigned DetailedRecordIncludesNestedMacroInstantiations : 1; + /// expansions. + unsigned DetailedRecordIncludesNestedMacroExpansions : 1; /// The implicit PCH included at the start of the translation unit, or empty. std::string ImplicitPCHInclude; @@ -104,6 +113,11 @@ public: /// compiler invocation and its buffers will be reused. bool RetainRemappedFileBuffers; + /// \brief The Objective-C++ ARC standard library that we should support, + /// by providing appropriate definitions to retrofit the standard library + /// with support for lifetime-qualified pointers. + ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary; + typedef std::vector<std::pair<std::string, std::string> >::iterator remapped_file_iterator; typedef std::vector<std::pair<std::string, std::string> >::const_iterator @@ -140,12 +154,13 @@ public: public: PreprocessorOptions() : UsePredefines(true), DetailedRecord(false), - DetailedRecordIncludesNestedMacroInstantiations(true), + DetailedRecordIncludesNestedMacroExpansions(true), DisablePCHValidation(false), DisableStatCache(false), DumpDeserializedPCHDecls(false), PrecompiledPreambleBytes(0, true), RemappedFilesKeepOriginalName(true), - RetainRemappedFileBuffers(false) { } + RetainRemappedFileBuffers(false), + ObjCXXARCStandardLibrary(ARCXX_nolib) { } void addMacroDef(llvm::StringRef Name) { Macros.push_back(std::make_pair(Name, false)); diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h index d7d2692..79a9916 100644 --- a/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/include/clang/Frontend/TextDiagnosticPrinter.h @@ -62,18 +62,17 @@ public: std::string &CaretLine, const std::string &SourceLine); - void EmitCaretDiagnostic(Diagnostic::Level Level, SourceLocation Loc, - CharSourceRange *Ranges, unsigned NumRanges, - const SourceManager &SM, - const FixItHint *Hints, - unsigned NumHints, - unsigned Columns, - unsigned OnMacroInst, - unsigned MacroSkipStart, - unsigned MacroSkipEnd); - virtual void HandleDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info); + +private: + void EmitCaretDiagnostic(SourceLocation Loc, CharSourceRange *Ranges, + unsigned NumRanges, const SourceManager &SM, + const FixItHint *Hints, + unsigned NumHints, unsigned Columns, + unsigned OnMacroInst, unsigned MacroSkipStart, + unsigned MacroSkipEnd); + }; } // end namespace clang diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index 3c34c2d..93d2c7d 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -19,6 +19,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/Support/raw_ostream.h" +#include "clang/Basic/Diagnostic.h" namespace llvm { class Triple; diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index 7c3d863..f429762 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -95,8 +95,8 @@ public: /// _Pragma expansion. This has a variety of magic semantics that this method /// sets up. It returns a new'd Lexer that must be delete'd when done. static Lexer *Create_PragmaLexer(SourceLocation SpellingLoc, - SourceLocation InstantiationLocStart, - SourceLocation InstantiationLocEnd, + SourceLocation ExpansionLocStart, + SourceLocation ExpansionLocEnd, unsigned TokLen, Preprocessor &PP); @@ -241,8 +241,8 @@ public: /// is not necessary to copy any data, then the returned string may /// not point into the provided buffer. /// - /// This method lexes at the instantiation depth of the given - /// location and does not jump to the instantiation or spelling + /// This method lexes at the expansion depth of the given + /// location and does not jump to the expansion or spelling /// location. static llvm::StringRef getSpelling(SourceLocation loc, llvm::SmallVectorImpl<char> &buffer, @@ -293,7 +293,19 @@ public: static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &Features); - + + /// \brief Returns true if the given MacroID location points at the first + /// token of the macro expansion. + static bool isAtStartOfMacroExpansion(SourceLocation loc, + const SourceManager &SM, + const LangOptions &LangOpts); + + /// \brief Returns true if the given MacroID location points at the last + /// token of the macro expansion. + static bool isAtEndOfMacroExpansion(SourceLocation loc, + const SourceManager &SM, + const LangOptions &LangOpts); + /// \brief Compute the preamble of the given file. /// /// The preamble of a file contains the initial comments, include directives, diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index ec3d9c5..0dbcd6d 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -167,7 +167,9 @@ public: bool AnyWide; bool Pascal; - const char *GetString() { return ResultBuf.data(); } + llvm::StringRef GetString() const { + return llvm::StringRef(ResultBuf.data(), GetStringLength()); + } unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); } unsigned GetNumStringChars() const { diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index 7c4cfb0..9e9d7cf 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -43,6 +43,10 @@ class MacroInfo { /// to. llvm::SmallVector<Token, 8> ReplacementTokens; + /// \brief Length in characters of the macro definition. + mutable unsigned DefinitionLength; + mutable bool IsDefinitionLengthCached : 1; + /// IsFunctionLike - True if this macro is a function-like macro, false if it /// is an object-like macro. bool IsFunctionLike : 1; @@ -116,6 +120,13 @@ public: /// getDefinitionEndLoc - Return the location of the last token in the macro. /// SourceLocation getDefinitionEndLoc() const { return EndLocation; } + + /// \brief Get length in characters of the macro definition. + unsigned getDefinitionLength(SourceManager &SM) const { + if (IsDefinitionLengthCached) + return DefinitionLength; + return getDefinitionLengthSlow(SM); + } /// isIdenticalTo - Return true if the specified macro definition is equal to /// this macro in spelling, arguments, and whitespace. This is used to emit @@ -232,6 +243,8 @@ public: /// AddTokenToBody - Add the specified token to the replacement text for the /// macro. void AddTokenToBody(const Token &Tok) { + assert(!IsDefinitionLengthCached && + "Changing replacement tokens after definition length got calculated"); ReplacementTokens.push_back(Tok); } @@ -248,6 +261,9 @@ public: assert(!IsDisabled && "Cannot disable an already-disabled macro!"); IsDisabled = true; } + +private: + unsigned getDefinitionLengthSlow(SourceManager &SM) const; }; } // end namespace clang diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index fd07a29..a794815 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -16,6 +16,7 @@ #include "clang/Lex/DirectoryLookup.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/DiagnosticIDs.h" #include "llvm/ADT/StringRef.h" #include <string> @@ -124,6 +125,24 @@ public: virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) { } + /// PragmaDiagnosticPush - This callback is invoked when a + /// #pragma gcc dianostic push directive is read. + virtual void PragmaDiagnosticPush(SourceLocation Loc, + llvm::StringRef Namespace) { + } + + /// PragmaDiagnosticPop - This callback is invoked when a + /// #pragma gcc dianostic pop directive is read. + virtual void PragmaDiagnosticPop(SourceLocation Loc, + llvm::StringRef Namespace) { + } + + /// PragmaDiagnostic - This callback is invoked when a + /// #pragma gcc dianostic directive is read. + virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace, + diag::Mapping mapping, llvm::StringRef Str) { + } + /// MacroExpands - This is called by /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is /// found. @@ -232,6 +251,24 @@ public: Second->PragmaMessage(Loc, Str); } + virtual void PragmaDiagnosticPush(SourceLocation Loc, + llvm::StringRef Namespace) { + First->PragmaDiagnosticPush(Loc, Namespace); + Second->PragmaDiagnosticPush(Loc, Namespace); + } + + virtual void PragmaDiagnosticPop(SourceLocation Loc, + llvm::StringRef Namespace) { + First->PragmaDiagnosticPop(Loc, Namespace); + Second->PragmaDiagnosticPop(Loc, Namespace); + } + + virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace, + diag::Mapping mapping, llvm::StringRef Str) { + First->PragmaDiagnostic(Loc, Namespace, mapping, Str); + Second->PragmaDiagnostic(Loc, Namespace, mapping, Str); + } + virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) { First->MacroExpands(MacroNameTok, MI); Second->MacroExpands(MacroNameTok, MI); diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index e498e9d..b38303a 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -38,13 +38,13 @@ namespace clang { class FileEntry; /// \brief Base class that describes a preprocessed entity, which may be a - /// preprocessor directive or macro instantiation. + /// preprocessor directive or macro expansion. class PreprocessedEntity { public: /// \brief The kind of preprocessed entity an object describes. enum EntityKind { - /// \brief A macro instantiation. - MacroInstantiationKind, + /// \brief A macro expansion. + MacroExpansionKind, /// \brief A preprocessing directive whose kind is not specified. /// @@ -110,31 +110,31 @@ namespace clang { void operator delete(void* data) throw(); }; - /// \brief Records the location of a macro instantiation. - class MacroInstantiation : public PreprocessedEntity { - /// \brief The name of the macro being instantiation. + /// \brief Records the location of a macro expansion. + class MacroExpansion : public PreprocessedEntity { + /// \brief The name of the macro being expanded. IdentifierInfo *Name; /// \brief The definition of this macro. MacroDefinition *Definition; public: - MacroInstantiation(IdentifierInfo *Name, SourceRange Range, - MacroDefinition *Definition) - : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name), + MacroExpansion(IdentifierInfo *Name, SourceRange Range, + MacroDefinition *Definition) + : PreprocessedEntity(MacroExpansionKind, Range), Name(Name), Definition(Definition) { } - /// \brief The name of the macro being instantiated. + /// \brief The name of the macro being expanded. IdentifierInfo *getName() const { return Name; } - /// \brief The definition of the macro being instantiated. + /// \brief The definition of the macro being expanded. MacroDefinition *getDefinition() const { return Definition; } // Implement isa/cast/dyncast/etc. static bool classof(const PreprocessedEntity *PE) { - return PE->getKind() == MacroInstantiationKind; + return PE->getKind() == MacroExpansionKind; } - static bool classof(const MacroInstantiation *) { return true; } + static bool classof(const MacroExpansion *) { return true; } }; @@ -256,11 +256,11 @@ namespace clang { /// \brief A record of the steps taken while preprocessing a source file, /// including the various preprocessing directives processed, macros - /// instantiated, etc. + /// expanded, etc. class PreprocessingRecord : public PPCallbacks { - /// \brief Whether we should include nested macro instantiations in + /// \brief Whether we should include nested macro expansions in /// the preprocessing record. - bool IncludeNestedMacroInstantiations; + bool IncludeNestedMacroExpansions; /// \brief Allocator used to store preprocessing objects. llvm::BumpPtrAllocator BumpAlloc; @@ -286,7 +286,7 @@ namespace clang { public: /// \brief Construct - explicit PreprocessingRecord(bool IncludeNestedMacroInstantiations); + explicit PreprocessingRecord(bool IncludeNestedMacroExpansions); /// \brief Allocate memory in the preprocessing record. void *Allocate(unsigned Size, unsigned Align = 8) { diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 76e3f59..f6f3205 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -29,6 +29,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Allocator.h" #include <vector> @@ -120,7 +121,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// Selectors - This table contains all the selectors in the program. Unlike /// IdentifierTable above, this table *isn't* populated by the preprocessor. - /// It is declared/instantiated here because it's role/lifetime is + /// It is declared/expanded here because it's role/lifetime is /// conceptually similar the IdentifierTable. In addition, the current control /// flow (in clang::ParseAST()), make it convenient to put here. /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to @@ -219,9 +220,9 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { /// previous macro value. llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo; - /// \brief Instantiation source location for the last macro that expanded + /// \brief Expansion source location for the last macro that expanded /// to no tokens. - SourceLocation LastEmptyMacroInstantiationLoc; + SourceLocation LastEmptyMacroExpansionLoc; // Various statistics we track for performance analysis. unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma; @@ -240,7 +241,15 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { unsigned NumCachedTokenLexers; TokenLexer *TokenLexerCache[TokenLexerCacheSize]; - /// \brief A record of the macro definitions and instantiations that + /// \brief Keeps macro expanded tokens for TokenLexers. + // + /// Works like a stack; a TokenLexer adds the macro expanded tokens that is + /// going to lex in the cache and when it finishes the tokens are removed + /// from the end of the cache. + llvm::SmallVector<Token, 16> MacroExpandedTokens; + std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack; + + /// \brief A record of the macro definitions and expansions that /// occurred during preprocessing. /// /// This is an optional side structure that can be enabled with @@ -371,10 +380,10 @@ public: macro_iterator macro_begin(bool IncludeExternalMacros = true) const; macro_iterator macro_end(bool IncludeExternalMacros = true) const; - /// \brief Instantiation source location for the last macro that expanded + /// \brief Expansion source location for the last macro that expanded /// to no tokens. - SourceLocation getLastEmptyMacroInstantiationLoc() const { - return LastEmptyMacroInstantiationLoc; + SourceLocation getLastEmptyMacroExpansionLoc() const { + return LastEmptyMacroExpansionLoc; } const std::string &getPredefines() const { return Predefines; } @@ -442,7 +451,7 @@ public: /// \brief Create a new preprocessing record, which will keep track of /// all macro expansions, macro definitions, etc. - void createPreprocessingRecord(bool IncludeNestedMacroInstantiations); + void createPreprocessingRecord(bool IncludeNestedMacroExpansions); /// EnterMainSourceFile - Enter the specified FileID as the main source file, /// which implicitly adds the builtin defines etc. @@ -658,7 +667,7 @@ public: /// getSpelling() - Return the 'spelling' of the token at the given /// location; does not go up to the spelling location or down to the - /// instantiation location. + /// expansion location. /// /// \param buffer A buffer which will be used only if the token requires /// "cleaning", e.g. if it contains trigraphs or escaped newlines @@ -721,7 +730,7 @@ public: /// CreateString - Plop the specified string into a scratch buffer and set the /// specified token's location and length to it. If specified, the source - /// location provides a location of the instantiation point of the token. + /// location provides a location of the expansion point of the token. void CreateString(const char *Buf, unsigned Len, Token &Tok, SourceLocation SourceLoc = SourceLocation()); @@ -744,6 +753,18 @@ public: return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, Features); } + /// \brief Returns true if the given MacroID location points at the first + /// token of the macro expansion. + bool isAtStartOfMacroExpansion(SourceLocation loc) const { + return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, Features); + } + + /// \brief Returns true if the given MacroID location points at the last + /// token of the macro expansion. + bool isAtEndOfMacroExpansion(SourceLocation loc) const { + return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, Features); + } + /// DumpToken - Print the token to stderr, used for debugging. /// void DumpToken(const Token &Tok, bool DumpFlags = false) const; @@ -770,6 +791,8 @@ public: void PrintStats(); + size_t getTotalMemory() const; + /// HandleMicrosoftCommentPaste - When the macro expander pastes together a /// comment (/##/) in microsoft mode, this method handles updating the current /// state, returning the token on the next source line. @@ -977,6 +1000,16 @@ private: /// the macro should not be expanded return true, otherwise return false. bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI); + /// \brief Cache macro expanded tokens for TokenLexers. + // + /// Works like a stack; a TokenLexer adds the macro expanded tokens that is + /// going to lex in the cache and when it finishes the tokens are removed + /// from the end of the cache. + Token *cacheMacroExpandedTokens(TokenLexer *tokLexer, + llvm::ArrayRef<Token> tokens); + void removeCachedMacroExpandedTokensOfLastLexer(); + friend void TokenLexer::ExpandFunctionArguments(); + /// isNextPPTokenLParen - Determine whether the next preprocessor token to be /// lexed is a '('. If so, consume the token and return true, if not, this /// method should have no observable side-effect on the lexed tokens. @@ -986,7 +1019,7 @@ private: /// invoked to read all of the formal arguments specified for the macro /// invocation. This returns null on error. MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI, - SourceLocation &InstantiationEnd); + SourceLocation &ExpansionEnd); /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded /// as a builtin macro, handle it and return the next token as 'Tok'. diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h index edcfcc10d..9cf11d9 100644 --- a/include/clang/Lex/Token.h +++ b/include/clang/Lex/Token.h @@ -63,9 +63,7 @@ class Token { /// Kind - The actual flavor of token this is. /// - unsigned char Kind; // DON'T make Kind a 'tok::TokenKind'; - // MSVC will treat it as a signed char and - // TokenKinds > 127 won't be handled correctly. + unsigned short Kind; /// Flags - Bits we track about this token, members of the TokenFlags enum. unsigned char Flags; diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h index 6ae00cd..45ff8a0 100644 --- a/include/clang/Lex/TokenLexer.h +++ b/include/clang/Lex/TokenLexer.h @@ -43,10 +43,13 @@ class TokenLexer { /// Tokens - This is the pointer to an array of tokens that the macro is /// defined to, with arguments expanded for function-like macros. If this is /// a token stream, these are the tokens we are returning. This points into - /// the macro definition we are lexing from, a scratch buffer allocated from - /// the preprocessor's bump pointer allocator, or some other buffer that we - /// may or may not own (depending on OwnsTokens). + /// the macro definition we are lexing from, a cache buffer that is owned by + /// the preprocessor, or some other buffer that we may or may not own + /// (depending on OwnsTokens). + /// Note that if it points into Preprocessor's cache buffer, the Preprocessor + /// may update the pointer as needed. const Token *Tokens; + friend class Preprocessor; /// NumTokens - This is the length of the Tokens array. /// @@ -56,9 +59,20 @@ class TokenLexer { /// unsigned CurToken; - /// InstantiateLocStart/End - The source location range where this macro was - /// instantiated. - SourceLocation InstantiateLocStart, InstantiateLocEnd; + /// ExpandLocStart/End - The source location range where this macro was + /// expanded. + SourceLocation ExpandLocStart, ExpandLocEnd; + + /// \brief Source location pointing at the source location entry chunk that + /// was reserved for the current macro expansion. + SourceLocation MacroExpansionStart; + + /// \brief The offset of the macro expansion in the + /// "source location address space". + unsigned MacroStartSLocOffset; + + /// \brief FileID/offset of the start of the macro definition. + std::pair<FileID, unsigned> MacroDefStartInfo; /// Lexical information about the expansion point of the macro: the identifier /// that the macro expanded from had these properties. @@ -148,9 +162,14 @@ private: /// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes /// together to form a comment that comments out everything in the current /// macro, other active macros, and anything left on the current physical - /// source line of the instantiated buffer. Handle this by returning the + /// source line of the expanded buffer. Handle this by returning the /// first token on the next line. void HandleMicrosoftCommentPaste(Token &Tok); + + /// \brief If \arg loc is a FileID and points inside the current macro + /// definition, returns the appropriate source location pointing at the + /// macro expansion source location entry. + SourceLocation getMacroExpansionLocation(SourceLocation loc) const; }; } // end namespace clang diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index e4cdc27..8f49dda 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_PARSE_PARSER_H #include "clang/Basic/Specifiers.h" +#include "clang/Basic/DelayedCleanupPool.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/CodeCompletionHandler.h" #include "clang/Sema/Sema.h" @@ -170,6 +171,10 @@ class Parser : public CodeCompletionHandler { /// Factory object for creating AttributeList objects. AttributeFactory AttrFactory; + /// \brief Gathers and cleans up objects when parsing of a top-level + /// declaration is finished. + DelayedCleanupPool TopLevelDeclCleanupPool; + public: Parser(Preprocessor &PP, Sema &Actions); ~Parser(); @@ -419,25 +424,7 @@ private: Tok.setAnnotationValue(ER.get()); } - /// TryAnnotateTypeOrScopeToken - If the current token position is on a - /// typename (possibly qualified in C++) or a C++ scope specifier not followed - /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens - /// with a single annotation token representing the typename or C++ scope - /// respectively. - /// This simplifies handling of C++ scope specifiers and allows efficient - /// backtracking without the need to re-parse and resolve nested-names and - /// typenames. - /// It will mainly be called when we expect to treat identifiers as typenames - /// (if they are typenames). For example, in C we do not expect identifiers - /// inside expressions to be treated as typenames so it will not be called - /// for expressions in C. - /// - /// This returns true if the token was annotated. bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false); - - /// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but - /// only annotates C++ scope specifiers. This returns true if there - /// was an unrecoverable error. bool TryAnnotateCXXScopeToken(bool EnteringContext = false); /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens, @@ -467,7 +454,12 @@ private: bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, bool &isInvalid); - + + /// \brief Get the TemplateIdAnnotation from the token and put it in the + /// cleanup pool so that it gets destroyed when parsing the current top level + /// declaration is finished. + TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok); + /// TentativeParsingAction - An object that is used as a kind of "tentative /// parsing transaction". It gets instantiated to mark the token position and /// after the token consumption is done, Commit() or Revert() is called to @@ -507,12 +499,6 @@ private: }; - /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'), - /// this helper function matches and consumes the specified RHS token if - /// present. If not present, it emits the specified diagnostic indicating - /// that the parser failed to match the RHS of the token at LHSLoc. LHSName - /// should be the name of the unmatched LHS token. This returns the location - /// of the consumed token. SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok, SourceLocation LHSLoc); @@ -1125,10 +1111,10 @@ private: ExprResult ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, bool &NotCastExpr, - ParsedType TypeOfCast); + bool isTypeCast); ExprResult ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand = false, - ParsedType TypeOfCast = ParsedType()); + bool isTypeCast = false); /// Returns true if the next token would start a postfix-expression /// suffix. @@ -1169,7 +1155,7 @@ private: }; ExprResult ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, - ParsedType TypeOfCast, + bool isTypeCast, ParsedType &CastTy, SourceLocation &RParenLoc); @@ -1328,6 +1314,9 @@ private: StmtResult ParseDefaultStatement(ParsedAttributes &Attr); StmtResult ParseCompoundStatement(ParsedAttributes &Attr, bool isStmtExpr = false); + StmtResult ParseCompoundStatement(ParsedAttributes &Attr, + bool isStmtExpr, + unsigned ScopeFlags); StmtResult ParseCompoundStatementBody(bool isStmtExpr = false); bool ParseParenExprOrCondition(ExprResult &ExprResult, Decl *&DeclResult, @@ -1375,6 +1364,7 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, StmtResult ParseObjCTryStmt(SourceLocation atLoc); StmtResult ParseObjCThrowStmt(SourceLocation atLoc); StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc); + StmtResult ParseObjCAutoreleasePoolStmt(SourceLocation atLoc); //===--------------------------------------------------------------------===// @@ -1439,7 +1429,7 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), bool SuppressDeclarations = false); - void ParseSpecifierQualifierList(DeclSpec &DS); + void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none); void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, ObjCTypeNameContext Context); @@ -1616,7 +1606,10 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, TypeResult ParseTypeName(SourceRange *Range = 0, Declarator::TheContext Context - = Declarator::TypeNameContext); + = Declarator::TypeNameContext, + ObjCDeclSpec *objcQuals = 0, + AccessSpecifier AS = AS_none, + Decl **OwnedType = 0); void ParseBlockId(); void ProhibitAttributes(ParsedAttributesWithRange &attrs) { @@ -1742,10 +1735,15 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, ParsedAttributes &attrs, bool RequiresArg = false); - void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc, - IdentifierInfo *FirstIdent, - SourceLocation FirstIdentLoc, - Declarator &D); + bool isFunctionDeclaratorIdentifierList(); + void ParseFunctionDeclaratorIdentifierList( + Declarator &D, + llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo); + void ParseParameterDeclarationClause( + Declarator &D, + ParsedAttributes &attrs, + llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo, + SourceLocation &EllipsisLoc); void ParseBracketDeclarator(Declarator &D); //===--------------------------------------------------------------------===// @@ -1766,7 +1764,8 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, Decl *ParseUsingDirectiveOrDeclaration(unsigned Context, const ParsedTemplateInfo &TemplateInfo, SourceLocation &DeclEnd, - ParsedAttributesWithRange &attrs); + ParsedAttributesWithRange &attrs, + Decl **OwnedType = 0); Decl *ParseUsingDirective(unsigned Context, SourceLocation UsingLoc, SourceLocation &DeclEnd, @@ -1775,7 +1774,8 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc, SourceLocation &DeclEnd, - AccessSpecifier AS = AS_none); + AccessSpecifier AS = AS_none, + Decl **OwnedType = 0); Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd); Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, diff --git a/include/clang/Rewrite/FixItRewriter.h b/include/clang/Rewrite/FixItRewriter.h index 26a0d72..bab9962 100644 --- a/include/clang/Rewrite/FixItRewriter.h +++ b/include/clang/Rewrite/FixItRewriter.h @@ -18,7 +18,6 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" #include "clang/Rewrite/Rewriter.h" -#include "llvm/ADT/SmallVector.h" namespace llvm { class raw_ostream; } diff --git a/include/clang/Rewrite/Rewriter.h b/include/clang/Rewrite/Rewriter.h index 7861e99..676744a 100644 --- a/include/clang/Rewrite/Rewriter.h +++ b/include/clang/Rewrite/Rewriter.h @@ -183,8 +183,11 @@ public: /// InsertText - Insert the specified string at the specified location in the /// original buffer. This method returns true (and does nothing) if the input /// location was not rewritable, false otherwise. + /// + /// \param indentNewLines if true new lines in the string are indented + /// using the indentation of the source line in position \arg Loc. bool InsertText(SourceLocation Loc, llvm::StringRef Str, - bool InsertAfter = true); + bool InsertAfter = true, bool indentNewLines = false); /// InsertTextAfter - Insert the specified string at the specified location in /// the original buffer. This method returns true (and does nothing) if diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h index 8b389b1..8e781cd 100644 --- a/include/clang/Sema/AnalysisBasedWarnings.h +++ b/include/clang/Sema/AnalysisBasedWarnings.h @@ -14,7 +14,6 @@ #ifndef LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H #define LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" namespace clang { @@ -50,6 +49,41 @@ private: enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 }; llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD; + /// \name Statistics + /// @{ + + /// \brief Number of function CFGs built and analyzed. + unsigned NumFunctionsAnalyzed; + + /// \brief Number of functions for which the CFG could not be successfully + /// built. + unsigned NumFunctionsWithBadCFGs; + + /// \brief Total number of blocks across all CFGs. + unsigned NumCFGBlocks; + + /// \brief Largest number of CFG blocks for a single function analyzed. + unsigned MaxCFGBlocksPerFunction; + + /// \brief Total number of CFGs with variables analyzed for uninitialized + /// uses. + unsigned NumUninitAnalysisFunctions; + + /// \brief Total number of variables analyzed for uninitialized uses. + unsigned NumUninitAnalysisVariables; + + /// \brief Max number of variables analyzed for uninitialized uses in a single + /// function. + unsigned MaxUninitAnalysisVariablesPerFunction; + + /// \brief Total number of block visits during uninitialized use analysis. + unsigned NumUninitAnalysisBlockVisits; + + /// \brief Max number of block visits during uninitialized use analysis of + /// a single function. + unsigned MaxUninitAnalysisBlockVisitsPerFunction; + + /// @} public: AnalysisBasedWarnings(Sema &s); @@ -58,6 +92,8 @@ public: const Decl *D, const BlockExpr *blkExpr); Policy getDefaultPolicy() { return DefaultPolicy; } + + void PrintStats() const; }; }} // end namespace clang::sema diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 72cd475..5d2d6c2 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -77,6 +77,8 @@ private: /// availability attribute. unsigned IsAvailability : 1; + unsigned AttrKind : 8; + /// \brief The location of the 'unavailable' keyword in an /// availability attribute. SourceLocation UnavailableLoc; @@ -123,6 +125,7 @@ private: DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false), IsAvailability(false), NextInPosition(0), NextInPool(0) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); + AttrKind = getKind(getName()); } AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc, @@ -141,6 +144,7 @@ private: new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); + AttrKind = getKind(getName()); } friend class AttributePool; @@ -148,20 +152,22 @@ private: public: enum Kind { // Please keep this list alphabetized. - AT_IBAction, // Clang-specific. - AT_IBOutlet, // Clang-specific. - AT_IBOutletCollection, // Clang-specific. AT_address_space, AT_alias, AT_aligned, AT_always_inline, AT_analyzer_noreturn, AT_annotate, + AT_arc_weakref_unavailable, AT_availability, // Clang-specific AT_base_check, AT_blocks, AT_carries_dependency, AT_cdecl, + AT_cf_consumed, // Clang-specific. + AT_cf_returns_autoreleased, // Clang-specific. + AT_cf_returns_not_retained, // Clang-specific. + AT_cf_returns_retained, // Clang-specific. AT_cleanup, AT_common, AT_const, @@ -179,32 +185,36 @@ public: AT_global, AT_gnu_inline, AT_host, + AT_IBAction, // Clang-specific. + AT_IBOutlet, // Clang-specific. + AT_IBOutletCollection, // Clang-specific. + AT_init_priority, AT_launch_bounds, AT_malloc, AT_may_alias, AT_mode, + AT_MsStruct, + AT_naked, AT_neon_polyvector_type, // Clang-specific. AT_neon_vector_type, // Clang-specific. - AT_naked, - AT_nodebug, - AT_noinline, AT_no_instrument_function, AT_nocommon, + AT_nodebug, + AT_noinline, AT_nonnull, AT_noreturn, AT_nothrow, - AT_nsobject, - AT_objc_exception, - AT_objc_method_family, - AT_cf_returns_not_retained, // Clang-specific. - AT_cf_returns_retained, // Clang-specific. - AT_ns_returns_not_retained, // Clang-specific. - AT_ns_returns_retained, // Clang-specific. - AT_ns_returns_autoreleased, // Clang-specific. - AT_cf_consumed, // Clang-specific. AT_ns_consumed, // Clang-specific. AT_ns_consumes_self, // Clang-specific. + AT_ns_returns_autoreleased, // Clang-specific. + AT_ns_returns_not_retained, // Clang-specific. + AT_ns_returns_retained, // Clang-specific. + AT_nsobject, + AT_objc_exception, AT_objc_gc, + AT_objc_method_family, + AT_objc_ownership, // Clang-specific. + AT_objc_precise_lifetime, // Clang-specific. AT_opencl_image_access, // OpenCL-specific. AT_opencl_kernel_function, // OpenCL-specific. AT_overloadable, // Clang-specific. @@ -216,6 +226,7 @@ public: AT_pcs, // ARM specific AT_pure, AT_regparm, + AT_reqd_wg_size, AT_section, AT_sentinel, AT_shared, @@ -231,11 +242,8 @@ public: AT_visibility, AT_warn_unused_result, AT_weak, - AT_weakref, AT_weak_import, - AT_reqd_wg_size, - AT_init_priority, - AT_MsStruct, + AT_weakref, IgnoredAttribute, UnknownAttribute }; @@ -256,7 +264,7 @@ public: bool isInvalid() const { return Invalid; } void setInvalid(bool b = true) const { Invalid = b; } - Kind getKind() const { return getKind(getName()); } + Kind getKind() const { return Kind(AttrKind); } static Kind getKind(const IdentifierInfo *Name); AttributeList *getNext() const { return NextInPosition; } diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index d322180..74b0105 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -185,12 +185,26 @@ public: /// is expected. CCC_ObjCMessageReceiver, /// \brief Code completion occurred on the right-hand side of a member - /// access expression. + /// access expression using the dot operator. /// /// The results of this completion are the members of the type being /// accessed. The type itself is available via /// \c CodeCompletionContext::getType(). - CCC_MemberAccess, + CCC_DotMemberAccess, + /// \brief Code completion occurred on the right-hand side of a member + /// access expression using the arrow operator. + /// + /// The results of this completion are the members of the type being + /// accessed. The type itself is available via + /// \c CodeCompletionContext::getType(). + CCC_ArrowMemberAccess, + /// \brief Code completion occurred on the right-hand side of an Objective-C + /// property access expression. + /// + /// The results of this completion are the members of the type being + /// accessed. The type itself is available via + /// \c CodeCompletionContext::getType(). + CCC_ObjCPropertyAccess, /// \brief Code completion occurred after the "enum" keyword, to indicate /// an enumeration name. CCC_EnumTag, @@ -235,6 +249,15 @@ public: /// \brief Code completion in a parenthesized expression, which means that /// we may also have types here in C and Objective-C (as well as in C++). CCC_ParenthesizedExpression, + /// \brief Code completion where an Objective-C instance message is expcted. + CCC_ObjCInstanceMessage, + /// \brief Code completion where an Objective-C class message is expected. + CCC_ObjCClassMessage, + /// \brief Code completion where a superclass of an Objective-C class is + /// expected. + CCC_ObjCSuperclass, + /// \brief Code completion where an Objective-C category name is expected. + CCC_ObjCCategoryName, /// \brief An unknown context, in which we are recovering from a parsing /// error and don't know which completions we should give. CCC_Recovery @@ -256,7 +279,8 @@ public: /// \brief Construct a new code-completion context of the given kind. CodeCompletionContext(enum Kind Kind, QualType T) : Kind(Kind) { - if (Kind == CCC_MemberAccess) + if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess || + Kind == CCC_ObjCPropertyAccess) BaseType = T; else PreferredType = T; diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 7ce4e00..a666499 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -40,6 +40,7 @@ namespace clang { class NamespaceDecl; class NestedNameSpecifier; class NestedNameSpecifierLoc; + class ObjCDeclSpec; class Preprocessor; class Declarator; struct TemplateIdAnnotation; @@ -153,6 +154,12 @@ public: /// copied. NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; + /// \brief Retrieve the location of the name in the last qualifier + /// in this nested name specifier. For example: + /// ::foo::bar<0>:: + /// ^~~ + SourceLocation getLastQualifierNameLoc() const; + /// No scope specifier. bool isEmpty() const { return !Range.isValid(); } /// A scope specifier is present, but may be valid or invalid. @@ -344,6 +351,8 @@ private: void SaveWrittenBuiltinSpecs(); void SaveStorageSpecifierAsWritten(); + ObjCDeclSpec *ObjCQualifiers; + static bool isTypeRep(TST T) { return (T == TST_typename || T == TST_typeofType || T == TST_underlyingType); @@ -383,7 +392,8 @@ public: ProtocolQualifiers(0), NumProtocolQualifiers(0), ProtocolLocs(0), - writtenBS() { + writtenBS(), + ObjCQualifiers(0) { } ~DeclSpec() { delete [] ProtocolQualifiers; @@ -653,6 +663,9 @@ public: return writtenBS; } + ObjCDeclSpec *getObjCQualifiers() const { return ObjCQualifiers; } + void setObjCQualifiers(ObjCDeclSpec *quals) { ObjCQualifiers = quals; } + /// isMissingDeclaratorOk - This checks if this DeclSpec can stand alone, /// without a Declarator. Only tag declspecs can stand alone. bool isMissingDeclaratorOk(); @@ -689,7 +702,10 @@ public: DQ_PR_copy = 0x20, DQ_PR_nonatomic = 0x40, DQ_PR_setter = 0x80, - DQ_PR_atomic = 0x100 + DQ_PR_atomic = 0x100, + DQ_PR_weak = 0x200, + DQ_PR_strong = 0x400, + DQ_PR_unsafe_unretained = 0x800 }; @@ -723,7 +739,7 @@ private: ObjCDeclQualifier objcDeclQualifier : 6; // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind - unsigned PropertyAttributes : 9; + unsigned PropertyAttributes : 12; IdentifierInfo *GetterName; // getter name of NULL if no getter IdentifierInfo *SetterName; // setter name of NULL if no setter }; @@ -751,7 +767,9 @@ public: /// \brief A destructor name. IK_DestructorName, /// \brief A template-id, e.g., f<int>. - IK_TemplateId + IK_TemplateId, + /// \brief An implicit 'self' parameter + IK_ImplicitSelfParam } Kind; /// \brief Anonymous union that holds extra data associated with the @@ -804,7 +822,7 @@ public: SourceLocation EndLocation; UnqualifiedId() : Kind(IK_Identifier), Identifier(0) { } - + /// \brief Do not use this copy constructor. It is temporary, and only /// exists because we are holding FieldDeclarators in a SmallVector when we /// don't actually need them. @@ -831,6 +849,7 @@ public: /// \brief Determine what kind of name we have. IdKind getKind() const { return Kind; } + void setKind(IdKind kind) { Kind = kind; } /// \brief Specify that this unqualified-id was parsed as an identifier. /// @@ -1078,6 +1097,10 @@ struct DeclaratorChunk { /// If this is an invalid location, there is no ref-qualifier. unsigned RefQualifierLoc; + /// \brief The location of the 'mutable' qualifer in a lambda-declarator, if + /// any. + unsigned MutableLoc; + /// \brief When ExceptionSpecType isn't EST_None or EST_Delayed, the /// location of the keyword introducing the spec. unsigned ExceptionSpecLoc; @@ -1139,10 +1162,19 @@ struct DeclaratorChunk { return SourceLocation::getFromRawEncoding(RefQualifierLoc); } + /// \brief Retrieve the location of the 'mutable' qualifier, if any. + SourceLocation getMutableLoc() const { + return SourceLocation::getFromRawEncoding(MutableLoc); + } + /// \brief Determine whether this function declaration contains a /// ref-qualifier. bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); } + /// \brief Determine whether this lambda-declarator contains a 'mutable' + /// qualifier. + bool hasMutableQualifier() const { return getMutableLoc().isValid(); } + /// \brief Get the type of exception specification this function has. ExceptionSpecificationType getExceptionSpecType() const { return static_cast<ExceptionSpecificationType>(ExceptionSpecType); @@ -1266,6 +1298,7 @@ struct DeclaratorChunk { unsigned TypeQuals, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, + SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceLocation ESpecLoc, ParsedType *Exceptions, @@ -1339,7 +1372,9 @@ public: ForContext, // Declaration within first part of a for loop. ConditionContext, // Condition declaration in a C++ if/switch/while/for. TemplateParamContext,// Within a template parameter list. + CXXNewContext, // C++ new-expression. CXXCatchContext, // C++ catch exception-declaration + ObjCCatchContext, // Objective-C catch exception-declaration BlockLiteralContext, // Block literal declarator. TemplateTypeArgContext, // Template type argument. AliasDeclContext, // C++0x alias-declaration. @@ -1489,7 +1524,9 @@ public: case PrototypeContext: case ObjCPrototypeContext: case TemplateParamContext: + case CXXNewContext: case CXXCatchContext: + case ObjCCatchContext: case BlockLiteralContext: case TemplateTypeArgContext: return true; @@ -1511,9 +1548,11 @@ public: case PrototypeContext: case TemplateParamContext: case CXXCatchContext: + case ObjCCatchContext: return true; case TypeNameContext: + case CXXNewContext: case AliasDeclContext: case AliasTemplateContext: case ObjCPrototypeContext: @@ -1542,7 +1581,9 @@ public: case ObjCPrototypeContext: case TemplateParamContext: case CXXCatchContext: + case ObjCCatchContext: case TypeNameContext: + case CXXNewContext: case AliasDeclContext: case AliasTemplateContext: case BlockLiteralContext: @@ -1687,6 +1728,14 @@ public: return const_cast<Declarator*>(this)->getFunctionTypeInfo(); } + /// \brief Determine whether the declaration that will be produced from + /// this declaration will be a function. + /// + /// A declaration can declare a function even if the declarator itself + /// isn't a function declarator, if the type specifier refers to a function + /// type. This routine checks for both cases. + bool isDeclarationOfFunction() const; + /// takeAttributes - Takes attributes from the given parsed-attributes /// set and add them to this declarator. /// diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index 8395138..8ab9382 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -112,7 +112,7 @@ private: /// the complete parsing of the current declaration. class DelayedDiagnostic { public: - enum DDKind { Deprecation, Access }; + enum DDKind { Deprecation, Access, ForbiddenType }; unsigned char Kind; // actually a DDKind bool Triggered; @@ -135,6 +135,20 @@ public: return DD; } + static DelayedDiagnostic makeForbiddenType(SourceLocation loc, + unsigned diagnostic, + QualType type, + unsigned argument) { + DelayedDiagnostic DD; + DD.Kind = ForbiddenType; + DD.Triggered = false; + DD.Loc = loc; + DD.ForbiddenTypeData.Diagnostic = diagnostic; + DD.ForbiddenTypeData.OperandType = type.getAsOpaquePtr(); + DD.ForbiddenTypeData.Argument = argument; + return DD; + } + AccessedEntity &getAccessData() { assert(Kind == Access && "Not an access diagnostic."); return *reinterpret_cast<AccessedEntity*>(AccessData); @@ -155,6 +169,25 @@ public: DeprecationData.MessageLen); } + /// The diagnostic ID to emit. Used like so: + /// Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) + /// << diag.getForbiddenTypeOperand() + /// << diag.getForbiddenTypeArgument(); + unsigned getForbiddenTypeDiagnostic() const { + assert(Kind == ForbiddenType && "not a forbidden-type diagnostic"); + return ForbiddenTypeData.Diagnostic; + } + + unsigned getForbiddenTypeArgument() const { + assert(Kind == ForbiddenType && "not a forbidden-type diagnostic"); + return ForbiddenTypeData.Argument; + } + + QualType getForbiddenTypeOperand() const { + assert(Kind == ForbiddenType && "not a forbidden-type diagnostic"); + return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType); + } + private: union { /// Deprecation. @@ -164,6 +197,12 @@ private: size_t MessageLen; } DeprecationData; + struct { + unsigned Diagnostic; + unsigned Argument; + void *OperandType; + } ForbiddenTypeData; + /// Access control. char AccessData[sizeof(AccessedEntity)]; }; diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index e2b083e..072e1b5 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -49,6 +49,11 @@ public: /// instance and factory methods, respectively, with this selector. virtual std::pair<ObjCMethodList,ObjCMethodList> ReadMethodPool(Selector Sel); + /// \brief Load the set of namespaces that are known to the external source, + /// which will be used during typo correction. + virtual void ReadKnownNamespaces( + llvm::SmallVectorImpl<NamespaceDecl *> &Namespaces); + /// \brief Do last resort, unqualified lookup on a LookupResult that /// Sema cannot find. /// diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 5dc4438..df6138c 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -86,9 +86,13 @@ private: QualType Type; union { - /// \brief When Kind == EK_Variable, EK_Parameter, or EK_Member, - /// the VarDecl, ParmVarDecl, or FieldDecl, respectively. + /// \brief When Kind == EK_Variable or EK_Member, the VarDecl or + /// FieldDecl, respectively. DeclaratorDecl *VariableOrMember; + + /// \brief When Kind == EK_Parameter, the ParmVarDecl, with the + /// low bit indicating whether the parameter is "consumed". + uintptr_t Parameter; /// \brief When Kind == EK_Temporary, the type source information for /// the temporary. @@ -123,11 +127,6 @@ private: : Kind(EK_Variable), Parent(0), Type(Var->getType()), VariableOrMember(Var) { } - /// \brief Create the initialization entity for a parameter. - InitializedEntity(ParmVarDecl *Parm) - : Kind(EK_Parameter), Parent(0), Type(Parm->getType().getUnqualifiedType()), - VariableOrMember(Parm) { } - /// \brief Create the initialization entity for the result of a /// function, throwing an object, performing an explicit cast, or /// initializing a parameter for which there is no declaration. @@ -157,20 +156,29 @@ public: /// \brief Create the initialization entity for a parameter. static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm) { - InitializedEntity Res(Parm); - Res.Type = Context.getVariableArrayDecayedType(Res.Type); - return Res; + bool Consumed = (Context.getLangOptions().ObjCAutoRefCount && + Parm->hasAttr<NSConsumedAttr>()); + + InitializedEntity Entity; + Entity.Kind = EK_Parameter; + Entity.Type = Context.getVariableArrayDecayedType( + Parm->getType().getUnqualifiedType()); + Entity.Parent = 0; + Entity.Parameter + = (static_cast<uintptr_t>(Consumed) | reinterpret_cast<uintptr_t>(Parm)); + return Entity; } /// \brief Create the initialization entity for a parameter that is /// only known by its type. static InitializedEntity InitializeParameter(ASTContext &Context, - QualType Type) { + QualType Type, + bool Consumed) { InitializedEntity Entity; Entity.Kind = EK_Parameter; Entity.Type = Context.getVariableArrayDecayedType(Type); Entity.Parent = 0; - Entity.VariableOrMember = 0; + Entity.Parameter = (Consumed); return Entity; } @@ -268,6 +276,13 @@ public: /// \brief Determine whether this initialization allows the named return /// value optimization, which also applies to thrown objects. bool allowsNRVO() const; + + /// \brief Determine whether this initialization consumes the + /// parameter. + bool isParameterConsumed() const { + assert(getKind() == EK_Parameter && "Not a parameter"); + return (Parameter & 1); + } /// \brief Retrieve the base specifier. CXXBaseSpecifier *getBaseSpecifier() const { @@ -287,7 +302,7 @@ public: assert(getKind() == EK_Result && "No 'return' location!"); return SourceLocation::getFromRawEncoding(LocAndNRVO.Location); } - + /// \brief Determine the location of the 'throw' keyword when initializing /// an exception object. SourceLocation getThrowLoc() const { @@ -325,8 +340,10 @@ private: SIK_Value = IK_Value, ///< Value initialization SIK_ImplicitValue, ///< Implicit value initialization SIK_DirectCast, ///< Direct initialization due to a cast - /// \brief Direct initialization due to a C-style or functional cast. - SIK_DirectCStyleOrFunctionalCast + /// \brief Direct initialization due to a C-style cast. + SIK_DirectCStyleCast, + /// \brief Direct initialization due to a functional-style cast. + SIK_DirectFunctionalCast }; /// \brief The kind of initialization being performed. @@ -352,15 +369,29 @@ public: return InitializationKind(SIK_Direct, InitLoc, LParenLoc, RParenLoc); } - /// \brief Create a direct initialization due to a cast. - static InitializationKind CreateCast(SourceRange TypeRange, - bool IsCStyleCast) { - return InitializationKind(IsCStyleCast? SIK_DirectCStyleOrFunctionalCast - : SIK_DirectCast, + /// \brief Create a direct initialization due to a cast that isn't a C-style + /// or functional cast. + static InitializationKind CreateCast(SourceRange TypeRange) { + return InitializationKind(SIK_DirectCast, TypeRange.getBegin(), TypeRange.getBegin(), TypeRange.getEnd()); } + /// \brief Create a direct initialization for a C-style cast. + static InitializationKind CreateCStyleCast(SourceLocation StartLoc, + SourceRange TypeRange) { + return InitializationKind(SIK_DirectCStyleCast, + StartLoc, TypeRange.getBegin(), + TypeRange.getEnd()); + } + + /// \brief Create a direct initialization for a functional cast. + static InitializationKind CreateFunctionalCast(SourceRange TypeRange) { + return InitializationKind(SIK_DirectFunctionalCast, + TypeRange.getBegin(), TypeRange.getBegin(), + TypeRange.getEnd()); + } + /// \brief Create a copy initialization. static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc) { @@ -393,12 +424,24 @@ public: /// \brief Determine whether this initialization is an explicit cast. bool isExplicitCast() const { - return Kind == SIK_DirectCast || Kind == SIK_DirectCStyleOrFunctionalCast; + return Kind == SIK_DirectCast || + Kind == SIK_DirectCStyleCast || + Kind == SIK_DirectFunctionalCast; } /// \brief Determine whether this initialization is a C-style cast. bool isCStyleOrFunctionalCast() const { - return Kind == SIK_DirectCStyleOrFunctionalCast; + return Kind == SIK_DirectCStyleCast || Kind == SIK_DirectFunctionalCast; + } + + /// brief Determine whether this is a C-style cast. + bool isCStyleCast() const { + return Kind == SIK_DirectCStyleCast; + } + + /// brief Determine whether this is a functional-style cast. + bool isFunctionalCast() const { + return Kind == SIK_DirectFunctionalCast; } /// \brief Determine whether this initialization is an implicit @@ -448,10 +491,7 @@ public: DependentSequence, /// \brief A normal sequence. - NormalSequence, - - /// \brief A reference binding. - ReferenceBinding // FIXME: Still looks redundant, but complicated. + NormalSequence }; /// \brief Describes the kind of a particular step in an initialization @@ -500,7 +540,13 @@ public: SK_ObjCObjectConversion, /// \brief Array initialization (from an array rvalue). /// This is a GNU C extension. - SK_ArrayInit + SK_ArrayInit, + /// \brief Pass an object by indirect copy-and-restore. + SK_PassByIndirectCopyRestore, + /// \brief Pass an object by indirect restore. + SK_PassByIndirectRestore, + /// \brief Produce an Objective-C object pointer. + SK_ProduceObjCObject }; /// \brief A single step in the initialization sequence. @@ -774,6 +820,13 @@ public: /// \brief Add an array initialization step. void AddArrayInitStep(QualType T); + /// \brief Add a step to pass an object by indirect copy-restore. + void AddPassByIndirectCopyRestoreStep(QualType T, bool shouldCopy); + + /// \brief Add a step to "produce" an Objective-C object (by + /// retaining it). + void AddProduceObjCObjectStep(QualType T); + /// \brief Note that this initialization sequence failed. void SetFailed(FailureKind Failure) { SequenceKind = FailedSequence; diff --git a/include/clang/Sema/LocInfoType.h b/include/clang/Sema/LocInfoType.h new file mode 100644 index 0000000..e1d3ae9 --- /dev/null +++ b/include/clang/Sema/LocInfoType.h @@ -0,0 +1,63 @@ +//===--- LocInfoType.h - Parsed Type with Location Information---*- 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 LocInfoType class, which holds a type and its +// source-location information. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_SEMA_LOCINFOTYPE_H +#define LLVM_CLANG_SEMA_LOCINFOTYPE_H + +#include "clang/AST/Type.h" + +namespace clang { + +class TypeSourceInfo; + +/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator +/// parsing. +/// +/// LocInfoType is a "transient" type, only needed for passing to/from Parser +/// and Sema, when we want to preserve type source info for a parsed type. +/// It will not participate in the type system semantics in any way. +class LocInfoType : public Type { + enum { + // The last number that can fit in Type's TC. + // Avoids conflict with an existing Type class. + LocInfo = Type::TypeLast + 1 + }; + + TypeSourceInfo *DeclInfo; + + LocInfoType(QualType ty, TypeSourceInfo *TInfo) + : Type((TypeClass)LocInfo, ty, ty->isDependentType(), + ty->isInstantiationDependentType(), + ty->isVariablyModifiedType(), + ty->containsUnexpandedParameterPack()), + DeclInfo(TInfo) { + assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); + } + friend class Sema; + + public: + QualType getType() const { return getCanonicalTypeInternal(); } + TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; } + + void getAsStringInternal(std::string &Str, + const PrintingPolicy &Policy) const; + + static bool classof(const Type *T) { + return T->getTypeClass() == (TypeClass)LocInfo; + } + static bool classof(const LocInfoType *) { return true; } +}; + +} // end namespace clang + +#endif // LLVM_CLANG_SEMA_LOCINFOTYPE_H diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 55931f2..32d4cbd 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -77,6 +77,7 @@ namespace clang { ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7) ICK_Block_Pointer_Conversion, ///< Block Pointer conversions ICK_TransparentUnionConversion, /// Transparent Union Conversions + ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion ICK_Num_Conversion_Kinds ///< The number of conversion kinds }; @@ -100,10 +101,11 @@ namespace clang { /// 13.3.3.1.1) and are listed such that better conversion ranks /// have smaller values. enum ImplicitConversionRank { - ICR_Exact_Match = 0, ///< Exact Match - ICR_Promotion, ///< Promotion - ICR_Conversion, ///< Conversion - ICR_Complex_Real_Conversion ///< Complex <-> Real conversion + ICR_Exact_Match = 0, ///< Exact Match + ICR_Promotion, ///< Promotion + ICR_Conversion, ///< Conversion + ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion + ICR_Writeback_Conversion ///< ObjC ARC writeback conversion }; ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind); @@ -137,6 +139,10 @@ namespace clang { /// (C++ 4.2p2). unsigned DeprecatedStringLiteralToCharPtr : 1; + /// \brief Whether the qualification conversion involves a change in the + /// Objective-C lifetime (for automatic reference counting). + unsigned QualificationIncludesObjCLifetime : 1; + /// IncompatibleObjC - Whether this is an Objective-C conversion /// that we should warn about (if we actually use it). unsigned IncompatibleObjC : 1; @@ -163,6 +169,10 @@ namespace clang { /// non-static member function without a ref-qualifier. unsigned BindsImplicitObjectArgumentWithoutRefQualifier : 1; + /// \brief Whether this binds a reference to an object with a different + /// Objective-C lifetime qualifier. + unsigned ObjCLifetimeConversionBinding : 1; + /// FromType - The type that this conversion is converting /// from. This is an opaque pointer that can be translated into a /// QualType. diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index 7514633..95d2978 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -84,7 +84,10 @@ public: /// ThisScope - This is the scope of a struct/union/class definition, /// outside of any member function definition, where 'this' is nonetheless /// usable. - ThisScope = 0x1000 + ThisScope = 0x1000, + + /// TryScope - This is the scope of a C++ try statement. + TryScope = 0x2000 }; private: /// The parent scope for this scope. This is null for the translation-unit @@ -303,6 +306,9 @@ public: } return false; } + + /// \brief Determine whether this scope is a C++ 'try' block. + bool isTryScope() const { return getFlags() & Scope::TryScope; } typedef UsingDirectivesTy::iterator udir_iterator; typedef UsingDirectivesTy::const_iterator const_udir_iterator; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 6dd0d3c..263c1bd 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -20,6 +20,8 @@ #include "clang/Sema/IdentifierResolver.h" #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/DeclSpec.h" +#include "clang/Sema/LocInfoType.h" +#include "clang/Sema/TypoCorrection.h" #include "clang/AST/Expr.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" @@ -45,6 +47,8 @@ namespace clang { class ASTConsumer; class ASTContext; class ASTMutationListener; + class ASTReader; + class ASTWriter; class ArrayType; class AttributeList; class BlockDecl; @@ -108,6 +112,7 @@ namespace clang { class ObjCInterfaceDecl; class ObjCIvarDecl; template <class T> class ObjCList; + class ObjCMessageExpr; class ObjCMethodDecl; class ObjCPropertyDecl; class ObjCProtocolDecl; @@ -156,43 +161,6 @@ namespace sema { class TemplateDeductionInfo; } -/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator -/// parsing. -/// -/// LocInfoType is a "transient" type, only needed for passing to/from Parser -/// and Sema, when we want to preserve type source info for a parsed type. -/// It will not participate in the type system semantics in any way. -class LocInfoType : public Type { - enum { - // The last number that can fit in Type's TC. - // Avoids conflict with an existing Type class. - LocInfo = Type::TypeLast + 1 - }; - - TypeSourceInfo *DeclInfo; - - LocInfoType(QualType ty, TypeSourceInfo *TInfo) - : Type((TypeClass)LocInfo, ty, ty->isDependentType(), - ty->isVariablyModifiedType(), - ty->containsUnexpandedParameterPack()), - DeclInfo(TInfo) { - assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); - } - friend class Sema; - -public: - QualType getType() const { return getCanonicalTypeInternal(); } - TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; } - - void getAsStringInternal(std::string &Str, - const PrintingPolicy &Policy) const; - - static bool classof(const Type *T) { - return T->getTypeClass() == (TypeClass)LocInfo; - } - static bool classof(const LocInfoType *) { return true; } -}; - // FIXME: No way to easily map from TemplateTypeParmTypes to // TemplateTypeParmDecls, so we have this horrible PointerUnion. typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>, @@ -225,6 +193,9 @@ public: Diagnostic &Diags; SourceManager &SourceMgr; + /// \brief Flag indicating whether or not to collect detailed statistics. + bool CollectStats; + /// \brief Source of additional semantic information. ExternalSemaSource *ExternalSource; @@ -247,6 +218,10 @@ public: /// VisContext - Manages the stack for #pragma GCC visibility. void *VisContext; // Really a "PragmaVisStack*" + /// ExprNeedsCleanups - True if the current evaluation context + /// requires cleanups to be run at its conclusion. + bool ExprNeedsCleanups; + /// \brief Stack containing information about each of the nested /// function, block, and method scopes that are currently active. /// @@ -555,6 +530,9 @@ public: /// \brief The expression evaluation context. ExpressionEvaluationContext Context; + /// \brief Whether the enclosing context needed a cleanup. + bool ParentNeedsCleanups; + /// \brief The number of temporaries that were active when we /// entered this expression evaluation context. unsigned NumTemporaries; @@ -573,8 +551,10 @@ public: PotentiallyEmittedDiagnostics *PotentiallyDiagnosed; ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, - unsigned NumTemporaries) - : Context(Context), NumTemporaries(NumTemporaries), + unsigned NumTemporaries, + bool ParentNeedsCleanups) + : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups), + NumTemporaries(NumTemporaries), PotentiallyReferenced(0), PotentiallyDiagnosed(0) { } void addReferencedDecl(SourceLocation Loc, Decl *Decl) { @@ -712,7 +692,9 @@ public: ASTContext &getASTContext() const { return Context; } ASTConsumer &getASTConsumer() const { return Consumer; } ASTMutationListener *getASTMutationListener() const; - + + void PrintStats() const; + /// \brief Helper class that creates diagnostics with optional /// template instantiation stacks. /// @@ -766,7 +748,7 @@ public: return FunctionScopes.back(); } - bool hasAnyErrorsInThisFunction() const; + bool hasAnyUnrecoverableErrorsInThisFunction() const; /// \brief Retrieve the current block, if any. sema::BlockScopeInfo *getCurBlock(); @@ -778,7 +760,6 @@ public: // Type Analysis / Processing: SemaType.cpp. // - QualType adjustParameterType(QualType T); QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs); QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVR) { return BuildQualifiedType(T, Loc, Qualifiers::fromCVRMask(CVR)); @@ -805,9 +786,8 @@ public: SourceLocation Loc, DeclarationName Entity); QualType BuildParenType(QualType T); - TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S, - TagDecl **OwnedDecl = 0, - bool AllowAutoInTypeName = false); + TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S); + TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy); TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, TypeSourceInfo *ReturnTypeInfo); /// \brief Package the given type and TSI into a ParsedType. @@ -838,7 +818,7 @@ public: const FunctionProtoType *Source, SourceLocation SourceLoc); TypeResult ActOnTypeName(Scope *S, Declarator &D); - + bool RequireCompleteType(SourceLocation Loc, QualType T, const PartialDiagnostic &PD, std::pair<SourceLocation, PartialDiagnostic> Note); @@ -864,7 +844,7 @@ public: // Symbol table / Decl tracking callbacks: SemaDecl.cpp. // - DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr); + DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = 0); void DiagnoseUseOfUnimplementedSelectors(); @@ -983,8 +963,7 @@ public: SourceLocation NameLoc, const Token &NextToken); - Decl *ActOnDeclarator(Scope *S, Declarator &D, - bool IsFunctionDefintion = false); + Decl *ActOnDeclarator(Scope *S, Declarator &D); Decl *HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, @@ -1305,13 +1284,20 @@ public: bool IsForUsingDecl); bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl); - bool TryImplicitConversion(InitializationSequence &Sequence, - const InitializedEntity &Entity, - Expr *From, - bool SuppressUserConversions, - bool AllowExplicit, - bool InOverloadResolution, - bool CStyle); + /// \brief Checks availability of the function depending on the current + /// function context.Inside an unavailable function,unavailability is ignored. + /// + /// \returns true if \arg FD is unavailable and current context is inside + /// an available function, false otherwise. + bool isFunctionConsideredUnavailable(FunctionDecl *FD); + + ImplicitConversionSequence + TryImplicitConversion(Expr *From, QualType ToType, + bool SuppressUserConversions, + bool AllowExplicit, + bool InOverloadResolution, + bool CStyle, + bool AllowObjCWritebackConversion); bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType); bool IsFloatingPointPromotion(QualType FromType, QualType ToType); @@ -1321,6 +1307,8 @@ public: QualType& ConvertedType, bool &IncompatibleObjC); bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType, bool &IncompatibleObjC); + bool isObjCWritebackConversion(QualType FromType, QualType ToType, + QualType &ConvertedType); bool IsBlockPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType); bool FunctionArgTypesAreEqual(const FunctionProtoType *OldType, @@ -1338,14 +1326,17 @@ public: CXXCastPath &BasePath, bool IgnoreBaseAccess); bool IsQualificationConversion(QualType FromType, QualType ToType, - bool CStyle); + bool CStyle, bool &ObjCLifetimeConversion); + bool IsNoReturnConversion(QualType FromType, QualType ToType, + QualType &ResultTy); bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType); ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, const VarDecl *NRVOCandidate, QualType ResultType, - Expr *Value); + Expr *Value, + bool AllowNRVO = true); bool CanPerformCopyInitialization(const InitializedEntity &Entity, ExprResult Init); @@ -1614,6 +1605,8 @@ public: LookupRedeclarationWithLinkage, /// Look up the name of an Objective-C protocol. LookupObjCProtocolName, + /// Look up implicit 'self' parameter of an objective-c method. + LookupObjCImplicitSelfParam, /// \brief Look up any declaration with any name. LookupAnyName }; @@ -1640,6 +1633,16 @@ private: bool ConstThis, bool VolatileThis); + // \brief The set of known/encountered (unique, canonicalized) NamespaceDecls. + // + // The boolean value will be true to indicate that the namespace was loaded + // from an AST/PCH file, or false otherwise. + llvm::DenseMap<NamespaceDecl*, bool> KnownNamespaces; + + /// \brief Whether we have already loaded known namespaces from an extenal + /// source. + bool LoadedExternalKnownNamespaces; + public: /// \brief Look up a name, looking for a single declaration. Return /// null if the results were absent, ambiguous, or overloaded. @@ -1669,9 +1672,12 @@ public: DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class); - CXXConstructorDecl *LookupCopyConstructor(CXXRecordDecl *Class, - unsigned Quals, - bool *ConstParam = 0); + CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class, + unsigned Quals, + bool *ConstParam = 0); + CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, + bool RValueThis, unsigned ThisQuals, + bool *ConstParam = 0); CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); void ArgumentDependentLookup(DeclarationName Name, bool Operator, @@ -1713,11 +1719,13 @@ public: CTC_ObjCMessageReceiver }; - DeclarationName CorrectTypo(LookupResult &R, Scope *S, CXXScopeSpec *SS, - DeclContext *MemberContext = 0, - bool EnteringContext = false, - CorrectTypoContext CTC = CTC_Unknown, - const ObjCObjectPointerType *OPT = 0); + TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, + Sema::LookupNameKind LookupKind, + Scope *S, CXXScopeSpec *SS, + DeclContext *MemberContext = NULL, + bool EnteringContext = false, + CorrectTypoContext CTC = CTC_Unknown, + const ObjCObjectPointerType *OPT = NULL); void FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs, AssociatedNamespaceSet &AssociatedNamespaces, @@ -1853,14 +1861,20 @@ public: void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl, ObjCContainerDecl* IDecl); + void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D); + void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID); + enum MethodMatchStrategy { + MMS_loose, + MMS_strict + }; + /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns /// true, or false, accordingly. bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod, - bool matchBasedOnSizeAndAlignment = false, - bool matchBasedOnStrictEqulity = false); + MethodMatchStrategy strategy = MMS_strict); /// MatchAllMethodDeclarations - Check methods declaraed in interface or /// or protocol against those declared in their implementations. @@ -2073,10 +2087,13 @@ public: Expr *SynchExpr, Stmt *SynchBody); + StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body); + VarDecl *BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id); + Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D); StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, @@ -2130,6 +2147,9 @@ public: void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); + bool makeUnavailableInSystemHeader(SourceLocation loc, + llvm::StringRef message); + //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. @@ -2146,6 +2166,8 @@ public: void PopExpressionEvaluationContext(); + void DiscardCleanupsInEvaluationContext(); + void MarkDeclarationReferenced(SourceLocation Loc, Decl *D); void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T); void MarkDeclarationsReferencedInExpr(Expr *E); @@ -2177,6 +2199,11 @@ public: ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, UnqualifiedId &Name, bool HasTrailingLParen, bool IsAddressOfOperand); + void DecomposeUnqualifiedId(const UnqualifiedId &Id, + TemplateArgumentListInfo &Buffer, + DeclarationNameInfo &NameInfo, + const TemplateArgumentListInfo *&TemplateArgs); + bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, CorrectTypoContext CTC = CTC_Unknown); @@ -2232,8 +2259,7 @@ public: ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *Val); ExprResult ActOnParenOrParenListExpr(SourceLocation L, SourceLocation R, - MultiExprArg Val, - ParsedType TypeOfCast = ParsedType()); + MultiExprArg Val); /// ActOnStringLiteral - The specified tokens were lexed as pasted string /// fragments (e.g. "foo" "bar" L"baz"). @@ -2356,21 +2382,19 @@ public: MultiExprArg ExecConfig, SourceLocation GGGLoc); ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, - ParsedType Ty, SourceLocation RParenLoc, - Expr *Op); + Declarator &D, ParsedType &Ty, + SourceLocation RParenLoc, Expr *Op); ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op); - bool TypeIsVectorType(ParsedType Ty) { - return GetTypeFromParser(Ty)->isVectorType(); - } + /// \brief Build an altivec or OpenCL literal. + ExprResult BuildVectorLiteral(SourceLocation LParenLoc, + SourceLocation RParenLoc, Expr *E, + TypeSourceInfo *TInfo); ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME); - ExprResult ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc, - SourceLocation RParenLoc, Expr *E, - TypeSourceInfo *TInfo); ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty, @@ -2805,7 +2829,7 @@ public: ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, SourceLocation LAngleBracketLoc, - ParsedType Ty, + Declarator &D, SourceLocation RAngleBracketLoc, SourceLocation LParenLoc, Expr *E, @@ -2863,8 +2887,11 @@ public: ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc); //// ActOnCXXThrow - Parse throw expressions. - ExprResult ActOnCXXThrow(SourceLocation OpLoc, Expr *expr); - ExprResult CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E); + ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr); + ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, + bool IsThrownVarInScope); + ExprResult CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, + bool IsThrownVarInScope); /// ActOnCXXTypeConstructExpr - Parse construction of a specified type. /// Can be interpreted either as function-style casting ("int(x)") @@ -4290,12 +4317,27 @@ public: QualType *FunctionType, sema::TemplateDeductionInfo &Info); + /// brief A function argument from which we performed template argument + // deduction for a call. + struct OriginalCallArg { + OriginalCallArg(QualType OriginalParamType, + unsigned ArgIdx, + QualType OriginalArgType) + : OriginalParamType(OriginalParamType), ArgIdx(ArgIdx), + OriginalArgType(OriginalArgType) { } + + QualType OriginalParamType; + unsigned ArgIdx; + QualType OriginalArgType; + }; + TemplateDeductionResult FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, - sema::TemplateDeductionInfo &Info); + sema::TemplateDeductionInfo &Info, + llvm::SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = 0); TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, @@ -4701,7 +4743,7 @@ public: /// \brief The number of typos corrected by CorrectTypo. unsigned TyposCorrected; - typedef llvm::DenseMap<IdentifierInfo *, std::pair<llvm::StringRef, bool> > + typedef llvm::DenseMap<IdentifierInfo *, TypoCorrection> UnqualifiedTyposCorrectedMap; /// \brief A cache containing the results of typo correction for unqualified @@ -4806,7 +4848,7 @@ public: bool Complain = true); void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, - Decl *Pattern, Decl *Inst); + const Decl *Pattern, Decl *Inst); bool InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation, @@ -4982,6 +5024,15 @@ public: IdentifierInfo *PropertyIvar, SourceLocation PropertyIvarLoc); + enum ObjCSpecialMethodKind { + OSMK_None, + OSMK_Alloc, + OSMK_New, + OSMK_Copy, + OSMK_RetainingInit, + OSMK_NonRetainingInit + }; + struct ObjCArgInfo { IdentifierInfo *Name; SourceLocation NameLoc; @@ -5020,9 +5071,12 @@ public: const ObjCObjectPointerType *OPT, bool IsInstance); + bool inferObjCARCLifetime(ValueDecl *decl); + ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, + SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, @@ -5098,6 +5152,22 @@ public: SourceLocation RBracLoc, MultiExprArg Args); + ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, + ObjCBridgeCastKind Kind, + SourceLocation BridgeKeywordLoc, + TypeSourceInfo *TSInfo, + Expr *SubExpr); + + ExprResult ActOnObjCBridgedCast(Scope *S, + SourceLocation LParenLoc, + ObjCBridgeCastKind Kind, + SourceLocation BridgeKeywordLoc, + ParsedType Type, + SourceLocation RParenLoc, + Expr *SubExpr); + + bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall); + /// \brief Check whether the given new method is a valid override of the /// given overridden method, and set any properties that should be inherited. /// @@ -5105,7 +5175,7 @@ public: bool CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, const ObjCMethodDecl *Overridden, bool IsImplementation); - + /// \brief Check whether the given method overrides any methods in its class, /// calling \c CheckObjCMethodOverride for each overridden method. bool CheckObjCMethodOverrides(ObjCMethodDecl *NewMethod, DeclContext *DC); @@ -5208,12 +5278,26 @@ public: /// from the inner expression. ExprValueKind CastCategory(Expr *E); + /// \brief The kind of conversion being performed. + enum CheckedConversionKind { + /// \brief An implicit conversion. + CCK_ImplicitConversion, + /// \brief A C-style cast. + CCK_CStyleCast, + /// \brief A functional-style cast. + CCK_FunctionalCast, + /// \brief A cast other than a C-style cast. + CCK_OtherCast + }; + /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit /// cast. If there is already an implicit cast, merge into the existing one. /// If isLvalue, the result of the cast is an lvalue. ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK = VK_RValue, - const CXXCastPath *BasePath = 0); + const CXXCastPath *BasePath = 0, + CheckedConversionKind CCK + = CCK_ImplicitConversion); /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding /// to the conversion from scalar type ScalarTy to the Boolean type. @@ -5343,6 +5427,10 @@ public: /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol. IncompatibleObjCQualifiedId, + /// IncompatibleObjCWeakRef - Assigning a weak-unavailable object to an + /// object with __weak qualifier. + IncompatibleObjCWeakRef, + /// Incompatible - We reject this conversion outright, it is invalid to /// represent it in the AST. Incompatible @@ -5393,11 +5481,12 @@ public: ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence& ICS, AssignmentAction Action, - bool CStyle = false); + CheckedConversionKind CCK + = CCK_ImplicitConversion); ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const StandardConversionSequence& SCS, AssignmentAction Action, - bool CStyle); + CheckedConversionKind CCK); /// the following "Check" methods will return a valid/converted QualType /// or a null QualType (indicating an error diagnostic was issued). @@ -5459,7 +5548,8 @@ public: SourceLocation QuestionLoc); /// type checking for vector binary operators. - QualType CheckVectorOperands(SourceLocation l, ExprResult &lex, ExprResult &rex); + QualType CheckVectorOperands(ExprResult &lex, ExprResult &rex, + SourceLocation Loc, bool isCompAssign); QualType CheckVectorCompareOperands(ExprResult &lex, ExprResult &rx, SourceLocation l, bool isRel); @@ -5494,12 +5584,14 @@ public: ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc, QualType T1, QualType T2, bool &DerivedToBase, - bool &ObjCConversion); + bool &ObjCConversion, + bool &ObjCLifetimeConversion); /// CheckCastTypes - Check type constraints for casting between types under /// C semantics, or forward to CXXCheckCStyleCast in C++. - ExprResult CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *CastExpr, - CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath, + ExprResult CheckCastTypes(SourceLocation CastStartLoc, SourceRange TyRange, + QualType CastTy, Expr *CastExpr, CastKind &Kind, + ExprValueKind &VK, CXXCastPath &BasePath, bool FunctionalStyle = false); ExprResult checkUnknownAnyCast(SourceRange TyRange, QualType castType, @@ -5526,6 +5618,31 @@ public: ExprResult CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, Expr *CastExpr, CastKind &Kind, CXXCastPath &BasePath, bool FunctionalStyle); + + /// \brief Checks for valid expressions which can be cast to an ObjC + /// pointer without needing a bridge cast. + bool ValidObjCARCNoBridgeCastExpr(Expr *&Exp, QualType castType); + + /// \brief Checks for invalid conversions and casts between + /// retainable pointers and other pointer kinds. + void CheckObjCARCConversion(SourceRange castRange, QualType castType, + Expr *&op, CheckedConversionKind CCK); + + bool CheckObjCARCUnavailableWeakConversion(QualType castType, + QualType ExprType); + + /// checkRetainCycles - Check whether an Objective-C message send + /// might create an obvious retain cycle. + void checkRetainCycles(ObjCMessageExpr *msg); + void checkRetainCycles(Expr *receiver, Expr *argument); + + /// checkUnsafeAssigns - Check whether +1 expr is being assigned + /// to weak/__unsafe_unretained type. + bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS); + + /// checkUnsafeExprAssigns - Check whether +1 expr is being assigned + /// to weak/__unsafe_unretained expression. + void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS); /// CheckMessageArgumentTypes - Check types in an Obj-C message send. /// \param Method - May be null. @@ -5544,7 +5661,7 @@ public: QualType getMessageSendResultType(QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage); - + /// \brief If the given expression involves a message send to a method /// with a related result type, emit a note describing what happened. void EmitRelatedResultTypeNote(const Expr *E); @@ -5749,8 +5866,6 @@ public: llvm::SmallVectorImpl<CodeCompletionResult> &Results); //@} - void PrintStats() const {} - //===--------------------------------------------------------------------===// // Extra semantic analysis beyond the C type system @@ -5802,8 +5917,17 @@ private: unsigned format_idx, unsigned firstDataArg, bool isPrintf); - void CheckMemsetcpymoveArguments(const CallExpr *Call, - const IdentifierInfo *FnName); + /// \brief Enumeration used to describe which of the memory setting or copying + /// functions is being checked by \c CheckMemsetcpymoveArguments(). + enum CheckedMemoryFunction { + CMF_Memset, + CMF_Memcpy, + CMF_Memmove + }; + + void CheckMemsetcpymoveArguments(const CallExpr *Call, + CheckedMemoryFunction CMF, + IdentifierInfo *FnName); void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, SourceLocation ReturnLoc); @@ -5820,10 +5944,20 @@ private: protected: friend class Parser; - friend class InitializationSequence; + friend class InitializationSequence; + friend class ASTReader; + friend class ASTWriter; +public: /// \brief Retrieve the parser's current scope. - Scope *getCurScope() const { return CurScope; } + /// + /// This routine must only be used when it is certain that semantic analysis + /// and the parser are in precisely the same context, which is not the case + /// when, e.g., we are performing any kind of template instantiation. + /// Therefore, the only safe places to use this scope are in the parser + /// itself and in routines directly invoked from the parser and *never* from + /// template substitution or instantiation. + Scope *getCurScope() const { return CurScope; } }; /// \brief RAII object that enters a new expression evaluation context. diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h new file mode 100644 index 0000000..9965953 --- /dev/null +++ b/include/clang/Sema/TypoCorrection.h @@ -0,0 +1,105 @@ +//===--- TypoCorrection.h - Class for typo correction results ---*- 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 TypoCorrection class, which stores the results of +// Sema's typo correction (Sema::CorrectTypo). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_TYPOCORRECTION_H +#define LLVM_CLANG_SEMA_TYPOCORRECTION_H + +#include "clang/AST/DeclCXX.h" + +namespace clang { + +/// @brief Simple class containing the result of Sema::CorrectTypo +class TypoCorrection { +public: + TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl, + NestedNameSpecifier *NNS=NULL, unsigned distance=0) + : CorrectionName(Name), + CorrectionNameSpec(NNS), + CorrectionDecl(NameDecl), + EditDistance(distance) {} + + TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS=NULL, + unsigned distance=0) + : CorrectionName(Name->getDeclName()), + CorrectionNameSpec(NNS), + CorrectionDecl(Name), + EditDistance(distance) {} + + TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS=NULL, + unsigned distance=0) + : CorrectionName(Name), + CorrectionNameSpec(NNS), + CorrectionDecl(NULL), + EditDistance(distance) {} + + TypoCorrection() + : CorrectionName(), CorrectionNameSpec(NULL), CorrectionDecl(NULL), + EditDistance(0) {} + + /// \brief Gets the DeclarationName of the typo correction + DeclarationName getCorrection() const { return CorrectionName; } + IdentifierInfo* getCorrectionAsIdentifierInfo() const { + return CorrectionName.getAsIdentifierInfo(); + } + + /// \brief Gets the NestedNameSpecifier needed to use the typo correction + NestedNameSpecifier* getCorrectionSpecifier() const { + return CorrectionNameSpec; + } + void setCorrectionSpecifier(NestedNameSpecifier* NNS) { + CorrectionNameSpec = NNS; + } + + /// \brief Gets the "edit distance" of the typo correction from the typo + unsigned getEditDistance() const { return EditDistance; } + + /// \brief Gets the pointer to the declaration of the typo correction + NamedDecl* getCorrectionDecl() const { + return isKeyword() ? NULL : CorrectionDecl; + } + template <class DeclClass> + DeclClass *getCorrectionDeclAs() const { + return dyn_cast_or_null<DeclClass>(getCorrectionDecl()); + } + + void setCorrectionDecl(NamedDecl *CDecl) { + CorrectionDecl = CDecl; + if (!CorrectionName) + CorrectionName = CDecl->getDeclName(); + } + + std::string getAsString(const LangOptions &LO) const; + std::string getQuoted(const LangOptions &LO) const { + return "'" + getAsString(LO) + "'"; + } + + operator bool() const { return bool(CorrectionName); } + + static inline NamedDecl *KeywordDecl() { return (NamedDecl*)-1; } + bool isKeyword() const { return CorrectionDecl == KeywordDecl(); } + + // Returns true if the correction either is a keyword or has a known decl. + bool isResolved() const { return CorrectionDecl != NULL; } + +private: + // Results. + DeclarationName CorrectionName; + NestedNameSpecifier *CorrectionNameSpec; + NamedDecl *CorrectionDecl; + unsigned EditDistance; +}; + +} + +#endif diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index c881b23..11b8bed 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -371,7 +371,11 @@ namespace clang { /// \brief Record code for the table of offsets into the block /// of file source-location information. - FILE_SOURCE_LOCATION_OFFSETS = 45 + FILE_SOURCE_LOCATION_OFFSETS = 45, + + /// \brief Record code for the set of known namespaces, which are used + /// for typo correction. + KNOWN_NAMESPACES = 46 }; @@ -388,8 +392,8 @@ namespace clang { /// SM_SLOC_BUFFER_ENTRY record. SM_SLOC_BUFFER_BLOB = 3, /// \brief Describes a source location entry (SLocEntry) for a - /// macro instantiation. - SM_SLOC_INSTANTIATION_ENTRY = 4, + /// macro expansion. + SM_SLOC_EXPANSION_ENTRY = 4, /// \brief Describes the SourceManager's line table, with /// information about #line directives. SM_LINE_TABLE = 5 @@ -416,9 +420,8 @@ namespace clang { /// \brief Record types used within a preprocessor detail block. enum PreprocessorDetailRecordTypes { - /// \brief Describes a macro instantiation within the preprocessing - /// record. - PPD_MACRO_INSTANTIATION = 0, + /// \brief Describes a macro expansion within the preprocessing record. + PPD_MACRO_EXPANSION = 0, /// \brief Describes a macro definition within the preprocessing record. PPD_MACRO_DEFINITION = 1, @@ -922,6 +925,8 @@ namespace clang { EXPR_OBJC_MESSAGE_EXPR, /// \brief An ObjCIsa Expr record. EXPR_OBJC_ISA, + /// \breif An ObjCIndirectCopyRestoreExpr record. + EXPR_OBJC_INDIRECT_COPY_RESTORE, /// \brief An ObjCForCollectionStmt record. STMT_OBJC_FOR_COLLECTION, @@ -935,6 +940,8 @@ namespace clang { STMT_OBJC_AT_SYNCHRONIZED, /// \brief An ObjCAtThrowStmt record. STMT_OBJC_AT_THROW, + /// \brief An ObjCAutoreleasePoolStmt record. + STMT_OBJC_AUTORELEASE_POOL, // C++ @@ -968,8 +975,6 @@ namespace clang { EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr). EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type). - EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr). - EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type). EXPR_CXX_THIS, // CXXThisExpr EXPR_CXX_THROW, // CXXThrowExpr EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr @@ -999,14 +1004,25 @@ namespace clang { EXPR_PACK_EXPANSION, // PackExpansionExpr EXPR_SIZEOF_PACK, // SizeOfPackExpr + EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr - + EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr + // CUDA + EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr - EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr - // OpenCL - EXPR_ASTYPE // An AsTypeExpr record. + EXPR_ASTYPE, // AsTypeExpr + + // Microsoft + EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr). + EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type). + STMT_SEH_EXCEPT, // SEHExceptStmt + STMT_SEH_FINALLY, // SEHFinallyStmt + STMT_SEH_TRY, // SEHTryStmt + + // ARC + EXPR_OBJC_BRIDGED_CAST // ObjCBridgedCastExpr }; /// \brief The kinds of designators that can occur in a diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 8923e2a..9e210c3 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -625,6 +625,9 @@ private: /// \brief The OpenCL extension settings. llvm::SmallVector<uint64_t, 1> OpenCLExtensions; + /// \brief A list of the namespaces we've seen. + llvm::SmallVector<uint64_t, 4> KnownNamespaces; + //@} /// \brief Diagnostic IDs and their mappings that the user changed. @@ -1067,7 +1070,7 @@ public: /// /// \returns true if there was an error while reading the /// declarations for this declaration context. - virtual bool FindExternalLexicalDecls(const DeclContext *DC, + virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl<Decl*> &Decls); @@ -1125,6 +1128,11 @@ public: virtual std::pair<ObjCMethodList, ObjCMethodList> ReadMethodPool(Selector Sel); + /// \brief Load the set of namespaces that are known to the external source, + /// which will be used during typo correction. + virtual void ReadKnownNamespaces( + llvm::SmallVectorImpl<NamespaceDecl *> &Namespaces); + /// \brief Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 78a63ab..18e1501 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -383,7 +383,7 @@ public: /// are relative to the given system root. /// /// \param PPRec Record of the preprocessing actions that occurred while - /// preprocessing this file, e.g., macro instantiations + /// preprocessing this file, e.g., macro expansions void WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, const std::string &OutputFile, const char* isysroot); diff --git a/include/clang/Serialization/ChainedIncludesSource.h b/include/clang/Serialization/ChainedIncludesSource.h index 0c3e86f..f547902 100644 --- a/include/clang/Serialization/ChainedIncludesSource.h +++ b/include/clang/Serialization/ChainedIncludesSource.h @@ -47,7 +47,7 @@ protected: virtual DeclContextLookupResult FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); virtual void MaterializeVisibleDecls(const DeclContext *DC); - virtual bool FindExternalLexicalDecls(const DeclContext *DC, + virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl<Decl*> &Result); virtual void CompleteType(TagDecl *Tag); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h index 07cdbf5..de7b868 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h @@ -124,6 +124,10 @@ namespace ento { return F.add(K, L); } + static bool Contains(data_type L, key_type K) { + return L.contains(K); + } + static inline data_type MakeData(void* const* p) { return p ? data_type((const llvm::ImmutableListImpl<T>*) *p) : data_type(0); |