diff options
Diffstat (limited to 'include/clang/Sema/DeclSpec.h')
-rw-r--r-- | include/clang/Sema/DeclSpec.h | 216 |
1 files changed, 150 insertions, 66 deletions
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 0728e87..5b90784 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -23,14 +23,14 @@ #ifndef LLVM_CLANG_SEMA_DECLSPEC_H #define LLVM_CLANG_SEMA_DECLSPEC_H -#include "clang/Sema/AttributeList.h" -#include "clang/Sema/Ownership.h" #include "clang/AST/NestedNameSpecifier.h" -#include "clang/Lex/Token.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/Lambda.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/Specifiers.h" +#include "clang/Lex/Token.h" +#include "clang/Sema/AttributeList.h" +#include "clang/Sema/Ownership.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" @@ -276,6 +276,14 @@ public: static const TST TST_auto = clang::TST_auto; static const TST TST_unknown_anytype = clang::TST_unknown_anytype; static const TST TST_atomic = clang::TST_atomic; + static const TST TST_image1d_t = clang::TST_image1d_t; + static const TST TST_image1d_array_t = clang::TST_image1d_array_t; + static const TST TST_image1d_buffer_t = clang::TST_image1d_buffer_t; + static const TST TST_image2d_t = clang::TST_image2d_t; + static const TST TST_image2d_array_t = clang::TST_image2d_array_t; + static const TST TST_image3d_t = clang::TST_image3d_t; + static const TST TST_sampler_t = clang::TST_sampler_t; + static const TST TST_event_t = clang::TST_event_t; static const TST TST_error = clang::TST_error; // type-qualifiers @@ -283,7 +291,10 @@ public: TQ_unspecified = 0, TQ_const = 1, TQ_restrict = 2, - TQ_volatile = 4 + TQ_volatile = 4, + // This has no corresponding Qualifiers::TQ value, because it's not treated + // as a qualifier in our type system. + TQ_atomic = 8 }; /// ParsedSpecifiers - Flags to query which specifiers were applied. This is @@ -306,19 +317,20 @@ private: /*TSW*/unsigned TypeSpecWidth : 2; /*TSC*/unsigned TypeSpecComplex : 2; /*TSS*/unsigned TypeSpecSign : 2; - /*TST*/unsigned TypeSpecType : 5; + /*TST*/unsigned TypeSpecType : 6; unsigned TypeAltiVecVector : 1; unsigned TypeAltiVecPixel : 1; unsigned TypeAltiVecBool : 1; unsigned TypeSpecOwned : 1; // type-qualifiers - unsigned TypeQualifiers : 3; // Bitwise OR of TQ. + unsigned TypeQualifiers : 4; // Bitwise OR of TQ. // function-specifier unsigned FS_inline_specified : 1; unsigned FS_virtual_specified : 1; unsigned FS_explicit_specified : 1; + unsigned FS_noreturn_specified : 1; // friend-specifier unsigned Friend_specified : 1; @@ -326,8 +338,6 @@ private: // constexpr-specifier unsigned Constexpr_specified : 1; - /*SCS*/unsigned StorageClassSpecAsWritten : 3; - union { UnionParsedType TypeRep; Decl *DeclRep; @@ -360,13 +370,12 @@ private: /// TSTNameLoc provides source range info for tag types. SourceLocation TSTNameLoc; SourceRange TypeofParensRange; - SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; - SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc; + SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc; + SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc; WrittenBuiltinSpecs writtenBS; void SaveWrittenBuiltinSpecs(); - void SaveStorageSpecifierAsWritten(); ObjCDeclSpec *ObjCQualifiers; @@ -377,16 +386,16 @@ private: static bool isExprRep(TST T) { return (T == TST_typeofExpr || T == TST_decltype); } + + DeclSpec(const DeclSpec &) LLVM_DELETED_FUNCTION; + void operator=(const DeclSpec &) LLVM_DELETED_FUNCTION; +public: static bool isDeclRep(TST T) { return (T == TST_enum || T == TST_struct || T == TST_interface || T == TST_union || T == TST_class); } - DeclSpec(const DeclSpec &) LLVM_DELETED_FUNCTION; - void operator=(const DeclSpec &) LLVM_DELETED_FUNCTION; -public: - DeclSpec(AttributeFactory &attrFactory) : StorageClassSpec(SCS_unspecified), SCS_thread_specified(false), @@ -403,9 +412,9 @@ public: FS_inline_specified(false), FS_virtual_specified(false), FS_explicit_specified(false), + FS_noreturn_specified(false), Friend_specified(false), Constexpr_specified(false), - StorageClassSpecAsWritten(SCS_unspecified), Attrs(attrFactory), ProtocolQualifiers(0), NumProtocolQualifiers(0), @@ -493,6 +502,7 @@ public: SourceLocation getConstSpecLoc() const { return TQ_constLoc; } SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } + SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; } /// \brief Clear out all of the type qualifiers. void ClearTypeQualifiers() { @@ -500,6 +510,7 @@ public: TQ_constLoc = SourceLocation(); TQ_restrictLoc = SourceLocation(); TQ_volatileLoc = SourceLocation(); + TQ_atomicLoc = SourceLocation(); } // function-specifier @@ -512,6 +523,9 @@ public: bool isExplicitSpecified() const { return FS_explicit_specified; } SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; } + bool isNoreturnSpecified() const { return FS_noreturn_specified; } + SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; } + void ClearFunctionSpecs() { FS_inline_specified = false; FS_inlineLoc = SourceLocation(); @@ -519,6 +533,8 @@ public: FS_virtualLoc = SourceLocation(); FS_explicit_specified = false; FS_explicitLoc = SourceLocation(); + FS_noreturn_specified = false; + FS_noreturnLoc = SourceLocation(); } /// \brief Return true if any type-specifier has been found. @@ -533,10 +549,6 @@ public: /// DeclSpec includes. unsigned getParsedSpecifiers() const; - SCS getStorageClassSpecAsWritten() const { - return (SCS)StorageClassSpecAsWritten; - } - /// isEmpty - Return true if this declaration specifier is completely empty: /// no tokens were parsed in the production of it. bool isEmpty() const { @@ -602,12 +614,10 @@ public: bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const LangOptions &Lang); - bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); + bool setFunctionSpecInline(SourceLocation Loc); + bool setFunctionSpecVirtual(SourceLocation Loc); + bool setFunctionSpecExplicit(SourceLocation Loc); + bool setFunctionSpecNoreturn(SourceLocation Loc); bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); @@ -808,6 +818,20 @@ public: IK_ImplicitSelfParam } Kind; + struct OFI { + /// \brief The kind of overloaded operator. + OverloadedOperatorKind Operator; + + /// \brief The source locations of the individual tokens that name + /// the operator, e.g., the "new", "[", and "]" tokens in + /// operator new []. + /// + /// Different operators have different numbers of tokens in their name, + /// up to three. Any remaining source locations in this array will be + /// set to an invalid value for operators with fewer than three tokens. + unsigned SymbolLocations[3]; + }; + /// \brief Anonymous union that holds extra data associated with the /// parsed unqualified-id. union { @@ -817,19 +841,7 @@ public: /// \brief When Kind == IK_OperatorFunctionId, the overloaded operator /// that we parsed. - struct { - /// \brief The kind of overloaded operator. - OverloadedOperatorKind Operator; - - /// \brief The source locations of the individual tokens that name - /// the operator, e.g., the "new", "[", and "]" tokens in - /// operator new []. - /// - /// Different operators have different numbers of tokens in their name, - /// up to three. Any remaining source locations in this array will be - /// set to an invalid value for operators with fewer than three tokens. - unsigned SymbolLocations[3]; - } OperatorFunctionId; + struct OFI OperatorFunctionId; /// \brief When Kind == IK_ConversionFunctionId, the type that the /// conversion function names. @@ -1010,8 +1022,8 @@ struct DeclaratorChunk { }; struct PointerTypeInfo : TypeInfoCommon { - /// The type qualifiers: const/volatile/restrict. - unsigned TypeQuals : 3; + /// The type qualifiers: const/volatile/restrict/atomic. + unsigned TypeQuals : 4; /// The location of the const-qualifier, if any. unsigned ConstQualLoc; @@ -1022,6 +1034,9 @@ struct DeclaratorChunk { /// The location of the restrict-qualifier, if any. unsigned RestrictQualLoc; + /// The location of the _Atomic-qualifier, if any. + unsigned AtomicQualLoc; + void destroy() { } }; @@ -1036,8 +1051,8 @@ struct DeclaratorChunk { }; struct ArrayTypeInfo : TypeInfoCommon { - /// The type qualifiers for the array: const/volatile/restrict. - unsigned TypeQuals : 3; + /// The type qualifiers for the array: const/volatile/restrict/_Atomic. + unsigned TypeQuals : 4; /// True if this dimension included the 'static' keyword. bool hasStatic : 1; @@ -1259,16 +1274,16 @@ struct DeclaratorChunk { struct BlockPointerTypeInfo : TypeInfoCommon { /// For now, sema will catch these as invalid. - /// The type qualifiers: const/volatile/restrict. - unsigned TypeQuals : 3; + /// The type qualifiers: const/volatile/restrict/_Atomic. + unsigned TypeQuals : 4; void destroy() { } }; struct MemberPointerTypeInfo : TypeInfoCommon { - /// The type qualifiers: const/volatile/restrict. - unsigned TypeQuals : 3; + /// The type qualifiers: const/volatile/restrict/_Atomic. + unsigned TypeQuals : 4; // CXXScopeSpec has a constructor, so it can't be a direct member. // So we need some pointer-aligned storage and a bit of trickery. union { @@ -1422,6 +1437,9 @@ struct DeclaratorChunk { return I; } + bool isParen() const { + return Kind == Paren; + } }; /// \brief Described the kind of function definition (if any) provided for @@ -1783,33 +1801,41 @@ public: return DeclTypeInfo[i]; } - void DropFirstTypeObject() - { + void DropFirstTypeObject() { assert(!DeclTypeInfo.empty() && "No type chunks to drop."); DeclTypeInfo.front().destroy(); DeclTypeInfo.erase(DeclTypeInfo.begin()); } + /// Return the innermost (closest to the declarator) chunk of this + /// declarator that is not a parens chunk, or null if there are no + /// non-parens chunks. + const DeclaratorChunk *getInnermostNonParenChunk() const { + for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { + if (!DeclTypeInfo[i].isParen()) + return &DeclTypeInfo[i]; + } + return 0; + } + + /// Return the outermost (furthest from the declarator) chunk of + /// this declarator that is not a parens chunk, or null if there are + /// no non-parens chunks. + const DeclaratorChunk *getOutermostNonParenChunk() const { + for (unsigned i = DeclTypeInfo.size(), i_end = 0; i != i_end; --i) { + if (!DeclTypeInfo[i-1].isParen()) + return &DeclTypeInfo[i-1]; + } + return 0; + } + /// isArrayOfUnknownBound - This method returns true if the declarator /// is a declarator for an array of unknown bound (looking through /// parentheses). bool isArrayOfUnknownBound() const { - for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { - switch (DeclTypeInfo[i].Kind) { - case DeclaratorChunk::Paren: - continue; - case DeclaratorChunk::Function: - case DeclaratorChunk::Pointer: - case DeclaratorChunk::Reference: - case DeclaratorChunk::BlockPointer: - case DeclaratorChunk::MemberPointer: - return false; - case DeclaratorChunk::Array: - return !DeclTypeInfo[i].Arr.NumElts; - } - llvm_unreachable("Invalid type chunk"); - } - return false; + const DeclaratorChunk *chunk = getInnermostNonParenChunk(); + return (chunk && chunk->Kind == DeclaratorChunk::Array && + !chunk->Arr.NumElts); } /// isFunctionDeclarator - This method returns true if the declarator @@ -1866,7 +1892,54 @@ public: /// isn't a function declarator, if the type specifier refers to a function /// type. This routine checks for both cases. bool isDeclarationOfFunction() const; + + /// \brief Return true if this declaration appears in a context where a + /// function declarator would be a function declaration. + bool isFunctionDeclarationContext() const { + if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) + return false; + + switch (Context) { + case FileContext: + case MemberContext: + case BlockContext: + return true; + + case ForContext: + case ConditionContext: + case KNRTypeListContext: + case TypeNameContext: + case AliasDeclContext: + case AliasTemplateContext: + case PrototypeContext: + case ObjCParameterContext: + case ObjCResultContext: + case TemplateParamContext: + case CXXNewContext: + case CXXCatchContext: + case ObjCCatchContext: + case BlockLiteralContext: + case LambdaExprContext: + case TemplateTypeArgContext: + case TrailingReturnContext: + return false; + } + llvm_unreachable("unknown context kind!"); + } + /// \brief Return true if a function declarator at this position would be a + /// function declaration. + bool isFunctionDeclaratorAFunctionDeclaration() const { + if (!isFunctionDeclarationContext()) + return false; + + for (unsigned I = 0, N = getNumTypeObjects(); I != N; ++I) + if (getTypeObject(I).Kind != DeclaratorChunk::Paren) + return false; + + return true; + } + /// takeAttributes - Takes attributes from the given parsed-attributes /// set and add them to this declarator. /// @@ -1897,6 +1970,17 @@ public: return false; } + /// \brief Return a source range list of C++11 attributes associated + /// with the declarator. + void getCXX11AttributeRanges(SmallVector<SourceRange, 4> &Ranges) { + AttributeList *AttrList = Attrs.getList(); + while (AttrList) { + if (AttrList->isCXX11Attribute()) + Ranges.push_back(AttrList->getRange()); + AttrList = AttrList->getNext(); + } + } + void setAsmLabel(Expr *E) { AsmLabel = E; } Expr *getAsmLabel() const { return AsmLabel; } @@ -1996,7 +2080,7 @@ struct LambdaIntroducer { SourceRange Range; SourceLocation DefaultLoc; LambdaCaptureDefault Default; - llvm::SmallVector<LambdaCapture, 4> Captures; + SmallVector<LambdaCapture, 4> Captures; LambdaIntroducer() : Default(LCD_None) {} |