<div dir="ltr">Thanks, fixed and re-committed as r340215.</div><br><div class="gmail_quote"><div dir="ltr">On Mon, 13 Aug 2018 at 18:56, Reid Kleckner via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Mon Aug 13 18:55:37 2018<br>
New Revision: 339638<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=339638&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=339638&view=rev</a><br>
Log:<br>
Revert r339623 "Model type attributes as regular Attrs."<br>
<br>
This breaks compiling atlwin.h in Chromium. I'm sure the code is invalid<br>
in some way, but we put a lot of work into accepting it, and I'm sure<br>
rejecting it was not an intended consequence of this refactoring. :)<br>
<br>
Modified:<br>
cfe/trunk/include/clang/AST/ASTContext.h<br>
cfe/trunk/include/clang/AST/Attr.h<br>
cfe/trunk/include/clang/AST/Type.h<br>
cfe/trunk/include/clang/AST/TypeLoc.h<br>
cfe/trunk/include/clang/Basic/Attr.td<br>
cfe/trunk/include/clang/Sema/Sema.h<br>
cfe/trunk/include/clang/Serialization/ASTReader.h<br>
cfe/trunk/include/clang/Serialization/ASTWriter.h<br>
cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp<br>
cfe/trunk/lib/ARCMigrate/Transforms.cpp<br>
cfe/trunk/lib/AST/ASTContext.cpp<br>
cfe/trunk/lib/AST/Type.cpp<br>
cfe/trunk/lib/AST/TypeLoc.cpp<br>
cfe/trunk/lib/AST/TypePrinter.cpp<br>
cfe/trunk/lib/Sema/SemaDecl.cpp<br>
cfe/trunk/lib/Sema/SemaExpr.cpp<br>
cfe/trunk/lib/Sema/SemaInit.cpp<br>
cfe/trunk/lib/Sema/SemaObjCProperty.cpp<br>
cfe/trunk/lib/Sema/SemaType.cpp<br>
cfe/trunk/lib/Sema/TreeTransform.h<br>
cfe/trunk/lib/Serialization/ASTReader.cpp<br>
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
cfe/trunk/lib/StaticAnalyzer/Core/CheckerHelpers.cpp<br>
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/ASTContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/ASTContext.h (original)<br>
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Aug 13 18:55:37 2018<br>
@@ -31,7 +31,6 @@<br>
#include "clang/AST/TemplateName.h"<br>
#include "clang/AST/Type.h"<br>
#include "clang/Basic/AddressSpaces.h"<br>
-#include "clang/Basic/AttrKinds.h"<br>
#include "clang/Basic/IdentifierTable.h"<br>
#include "clang/Basic/LLVM.h"<br>
#include "clang/Basic/LangOptions.h"<br>
@@ -1423,7 +1422,7 @@ public:<br>
<br>
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;<br>
<br>
- QualType getAttributedType(attr::Kind attrKind,<br>
+ QualType getAttributedType(AttributedType::Kind attrKind,<br>
QualType modifiedType,<br>
QualType equivalentType);<br>
<br>
<br>
Modified: cfe/trunk/include/clang/AST/Attr.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/Attr.h (original)<br>
+++ cfe/trunk/include/clang/AST/Attr.h Mon Aug 13 18:55:37 2018<br>
@@ -113,19 +113,6 @@ public:<br>
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;<br>
};<br>
<br>
-class TypeAttr : public Attr {<br>
-protected:<br>
- TypeAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,<br>
- bool IsLateParsed)<br>
- : Attr(AK, R, SpellingListIndex, IsLateParsed) {}<br>
-<br>
-public:<br>
- static bool classof(const Attr *A) {<br>
- return A->getKind() >= attr::FirstTypeAttr &&<br>
- A->getKind() <= attr::LastTypeAttr;<br>
- }<br>
-};<br>
-<br>
class StmtAttr : public Attr {<br>
protected:<br>
StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,<br>
<br>
Modified: cfe/trunk/include/clang/AST/Type.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/Type.h (original)<br>
+++ cfe/trunk/include/clang/AST/Type.h Mon Aug 13 18:55:37 2018<br>
@@ -21,7 +21,6 @@<br>
#include "clang/AST/NestedNameSpecifier.h"<br>
#include "clang/AST/TemplateName.h"<br>
#include "clang/Basic/AddressSpaces.h"<br>
-#include "clang/Basic/AttrKinds.h"<br>
#include "clang/Basic/Diagnostic.h"<br>
#include "clang/Basic/ExceptionSpecificationType.h"<br>
#include "clang/Basic/LLVM.h"<br>
@@ -1871,16 +1870,7 @@ public:<br>
bool isObjCQualifiedClassType() const; // Class<foo><br>
bool isObjCObjectOrInterfaceType() const;<br>
bool isObjCIdType() const; // id<br>
-<br>
- /// Was this type written with the special inert-in-ARC __unsafe_unretained<br>
- /// qualifier?<br>
- ///<br>
- /// This approximates the answer to the following question: if this<br>
- /// translation unit were compiled in ARC, would this type be qualified<br>
- /// with __unsafe_unretained?<br>
- bool isObjCInertUnsafeUnretainedType() const {<br>
- return hasAttr(attr::ObjCInertUnsafeUnretained);<br>
- }<br>
+ bool isObjCInertUnsafeUnretainedType() const;<br>
<br>
/// Whether the type is Objective-C 'id' or a __kindof type of an<br>
/// object type, e.g., __kindof NSView * or __kindof id<br>
@@ -2094,10 +2084,6 @@ public:<br>
/// qualifiers from the outermost type.<br>
const ArrayType *castAsArrayTypeUnsafe() const;<br>
<br>
- /// Determine whether this type had the specified attribute applied to it<br>
- /// (looking through top-level type sugar).<br>
- bool hasAttr(attr::Kind AK) const;<br>
-<br>
/// Get the base element type of this type, potentially discarding type<br>
/// qualifiers. This should never be used when type qualifiers<br>
/// are meaningful.<br>
@@ -4207,7 +4193,56 @@ public:<br>
/// - the canonical type is VectorType(16, int)<br>
class AttributedType : public Type, public llvm::FoldingSetNode {<br>
public:<br>
- using Kind = attr::Kind;<br>
+ // It is really silly to have yet another attribute-kind enum, but<br>
+ // clang::attr::Kind doesn't currently cover the pure type attrs.<br>
+ enum Kind {<br>
+ // Expression operand.<br>
+ attr_address_space,<br>
+ attr_regparm,<br>
+ attr_vector_size,<br>
+ attr_neon_vector_type,<br>
+ attr_neon_polyvector_type,<br>
+<br>
+ FirstExprOperandKind = attr_address_space,<br>
+ LastExprOperandKind = attr_neon_polyvector_type,<br>
+<br>
+ // Enumerated operand (string or keyword).<br>
+ attr_objc_gc,<br>
+ attr_objc_ownership,<br>
+ attr_pcs,<br>
+ attr_pcs_vfp,<br>
+<br>
+ FirstEnumOperandKind = attr_objc_gc,<br>
+ LastEnumOperandKind = attr_pcs_vfp,<br>
+<br>
+ // No operand.<br>
+ attr_noreturn,<br>
+ attr_nocf_check,<br>
+ attr_cdecl,<br>
+ attr_fastcall,<br>
+ attr_stdcall,<br>
+ attr_thiscall,<br>
+ attr_regcall,<br>
+ attr_pascal,<br>
+ attr_swiftcall,<br>
+ attr_vectorcall,<br>
+ attr_inteloclbicc,<br>
+ attr_ms_abi,<br>
+ attr_sysv_abi,<br>
+ attr_preserve_most,<br>
+ attr_preserve_all,<br>
+ attr_ptr32,<br>
+ attr_ptr64,<br>
+ attr_sptr,<br>
+ attr_uptr,<br>
+ attr_nonnull,<br>
+ attr_ns_returns_retained,<br>
+ attr_nullable,<br>
+ attr_null_unspecified,<br>
+ attr_objc_kindof,<br>
+ attr_objc_inert_unsafe_unretained,<br>
+ attr_lifetimebound,<br>
+ };<br>
<br>
private:<br>
friend class ASTContext; // ASTContext creates these<br>
@@ -4215,7 +4250,7 @@ private:<br>
QualType ModifiedType;<br>
QualType EquivalentType;<br>
<br>
- AttributedType(QualType canon, attr::Kind attrKind, QualType modified,<br>
+ AttributedType(QualType canon, Kind attrKind, QualType modified,<br>
QualType equivalent)<br>
: Type(Attributed, canon, equivalent->isDependentType(),<br>
equivalent->isInstantiationDependentType(),<br>
@@ -4264,13 +4299,13 @@ public:<br>
static Kind getNullabilityAttrKind(NullabilityKind kind) {<br>
switch (kind) {<br>
case NullabilityKind::NonNull:<br>
- return attr::TypeNonNull;<br>
+ return attr_nonnull;<br>
<br>
case NullabilityKind::Nullable:<br>
- return attr::TypeNullable;<br>
+ return attr_nullable;<br>
<br>
case NullabilityKind::Unspecified:<br>
- return attr::TypeNullUnspecified;<br>
+ return attr_null_unspecified;<br>
}<br>
llvm_unreachable("Unknown nullability kind.");<br>
}<br>
<br>
Modified: cfe/trunk/include/clang/AST/TypeLoc.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)<br>
+++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Aug 13 18:55:37 2018<br>
@@ -15,7 +15,6 @@<br>
#ifndef LLVM_CLANG_AST_TYPELOC_H<br>
#define LLVM_CLANG_AST_TYPELOC_H<br>
<br>
-#include "clang/AST/Attr.h"<br>
#include "clang/AST/Decl.h"<br>
#include "clang/AST/NestedNameSpecifier.h"<br>
#include "clang/AST/TemplateBase.h"<br>
@@ -850,7 +849,16 @@ class SubstTemplateTypeParmPackTypeLoc :<br>
};<br>
<br>
struct AttributedLocInfo {<br>
- const Attr *TypeAttr;<br>
+ union {<br>
+ Expr *ExprOperand;<br>
+<br>
+ /// A raw SourceLocation.<br>
+ unsigned EnumOperandLoc;<br>
+ };<br>
+<br>
+ SourceRange OperandParens;<br>
+<br>
+ SourceLocation AttrLoc;<br>
};<br>
<br>
/// Type source information for an attributed type.<br>
@@ -859,10 +867,24 @@ class AttributedTypeLoc : public Concret<br>
AttributedType,<br>
AttributedLocInfo> {<br>
public:<br>
- attr::Kind getAttrKind() const {<br>
+ AttributedType::Kind getAttrKind() const {<br>
return getTypePtr()->getAttrKind();<br>
}<br>
<br>
+ bool hasAttrExprOperand() const {<br>
+ return (getAttrKind() >= AttributedType::FirstExprOperandKind &&<br>
+ getAttrKind() <= AttributedType::LastExprOperandKind);<br>
+ }<br>
+<br>
+ bool hasAttrEnumOperand() const {<br>
+ return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&<br>
+ getAttrKind() <= AttributedType::LastEnumOperandKind);<br>
+ }<br>
+<br>
+ bool hasAttrOperand() const {<br>
+ return hasAttrExprOperand() || hasAttrEnumOperand();<br>
+ }<br>
+<br>
bool isQualifier() const {<br>
return getTypePtr()->isQualifier();<br>
}<br>
@@ -875,16 +897,51 @@ public:<br>
return getInnerTypeLoc();<br>
}<br>
<br>
- /// The type attribute.<br>
- const Attr *getAttr() const {<br>
- return getLocalData()->TypeAttr;<br>
- }<br>
- void setAttr(const Attr *A) {<br>
- getLocalData()->TypeAttr = A;<br>
- }<br>
-<br>
- template<typename T> const T *getAttrAs() {<br>
- return dyn_cast_or_null<T>(getAttr());<br>
+ /// The location of the attribute name, i.e.<br>
+ /// __attribute__((regparm(1000)))<br>
+ /// ^~~~~~~<br>
+ SourceLocation getAttrNameLoc() const {<br>
+ return getLocalData()->AttrLoc;<br>
+ }<br>
+ void setAttrNameLoc(SourceLocation loc) {<br>
+ getLocalData()->AttrLoc = loc;<br>
+ }<br>
+<br>
+ /// The attribute's expression operand, if it has one.<br>
+ /// void *cur_thread __attribute__((address_space(21)))<br>
+ /// ^~<br>
+ Expr *getAttrExprOperand() const {<br>
+ assert(hasAttrExprOperand());<br>
+ return getLocalData()->ExprOperand;<br>
+ }<br>
+ void setAttrExprOperand(Expr *e) {<br>
+ assert(hasAttrExprOperand());<br>
+ getLocalData()->ExprOperand = e;<br>
+ }<br>
+<br>
+ /// The location of the attribute's enumerated operand, if it has one.<br>
+ /// void * __attribute__((objc_gc(weak)))<br>
+ /// ^~~~<br>
+ SourceLocation getAttrEnumOperandLoc() const {<br>
+ assert(hasAttrEnumOperand());<br>
+ return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);<br>
+ }<br>
+ void setAttrEnumOperandLoc(SourceLocation loc) {<br>
+ assert(hasAttrEnumOperand());<br>
+ getLocalData()->EnumOperandLoc = loc.getRawEncoding();<br>
+ }<br>
+<br>
+ /// The location of the parentheses around the operand, if there is<br>
+ /// an operand.<br>
+ /// void * __attribute__((objc_gc(weak)))<br>
+ /// ^ ^<br>
+ SourceRange getAttrOperandParensRange() const {<br>
+ assert(hasAttrOperand());<br>
+ return getLocalData()->OperandParens;<br>
+ }<br>
+ void setAttrOperandParensRange(SourceRange range) {<br>
+ assert(hasAttrOperand());<br>
+ getLocalData()->OperandParens = range;<br>
}<br>
<br>
SourceRange getLocalSourceRange() const {<br>
@@ -897,11 +954,21 @@ public:<br>
// ^~ ~~<br>
// That enclosure doesn't necessarily belong to a single attribute<br>
// anyway.<br>
- return getAttr() ? getAttr()->getRange() : SourceRange();<br>
+ SourceRange range(getAttrNameLoc());<br>
+ if (hasAttrOperand())<br>
+ range.setEnd(getAttrOperandParensRange().getEnd());<br>
+ return range;<br>
}<br>
<br>
void initializeLocal(ASTContext &Context, SourceLocation loc) {<br>
- setAttr(nullptr);<br>
+ setAttrNameLoc(loc);<br>
+ if (hasAttrExprOperand()) {<br>
+ setAttrOperandParensRange(SourceRange(loc));<br>
+ setAttrExprOperand(nullptr);<br>
+ } else if (hasAttrEnumOperand()) {<br>
+ setAttrOperandParensRange(SourceRange(loc));<br>
+ setAttrEnumOperandLoc(loc);<br>
+ }<br>
}<br>
<br>
QualType getInnerType() const {<br>
<br>
Modified: cfe/trunk/include/clang/Basic/Attr.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/Attr.td (original)<br>
+++ cfe/trunk/include/clang/Basic/Attr.td Mon Aug 13 18:55:37 2018<br>
@@ -494,7 +494,10 @@ class Attr {<br>
}<br>
<br>
/// A type attribute is not processed on a declaration or a statement.<br>
-class TypeAttr : Attr;<br>
+class TypeAttr : Attr {<br>
+ // By default, type attributes do not get an AST node.<br>
+ let ASTNode = 0;<br>
+}<br>
<br>
/// A stmt attribute is not processed on a declaration or a type.<br>
class StmtAttr : Attr;<br>
@@ -564,8 +567,6 @@ def AddressSpace : TypeAttr {<br>
let Spellings = [Clang<"address_space">];<br>
let Args = [IntArgument<"AddressSpace">];<br>
let Documentation = [Undocumented];<br>
- // Represented as a qualifier or DependentAddressSpaceType instead.<br>
- let ASTNode = 0;<br>
}<br>
<br>
def Alias : Attr {<br>
@@ -1223,7 +1224,7 @@ def LayoutVersion : InheritableAttr, Tar<br>
let Documentation = [LayoutVersionDocs];<br>
}<br>
<br>
-def LifetimeBound : DeclOrTypeAttr {<br>
+def LifetimeBound : InheritableAttr {<br>
let Spellings = [Clang<"lifetimebound", 0>];<br>
let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>;<br>
let Documentation = [LifetimeBoundDocs];<br>
@@ -1326,16 +1327,12 @@ def NeonPolyVectorType : TypeAttr {<br>
let Spellings = [Clang<"neon_polyvector_type">];<br>
let Args = [IntArgument<"NumElements">];<br>
let Documentation = [Undocumented];<br>
- // Represented as VectorType instead.<br>
- let ASTNode = 0;<br>
}<br>
<br>
def NeonVectorType : TypeAttr {<br>
let Spellings = [Clang<"neon_vector_type">];<br>
let Args = [IntArgument<"NumElements">];<br>
let Documentation = [Undocumented];<br>
- // Represented as VectorType instead.<br>
- let ASTNode = 0;<br>
}<br>
<br>
def ReturnsTwice : InheritableAttr {<br>
@@ -1510,14 +1507,6 @@ def TypeNullUnspecified : TypeAttr {<br>
let Documentation = [TypeNullUnspecifiedDocs];<br>
}<br>
<br>
-// This is a marker used to indicate that an __unsafe_unretained qualifier was<br>
-// ignored because ARC is not enabled. The usual representation for this<br>
-// qualifier is as an ObjCOwnership attribute with Kind == "none".<br>
-def ObjCInertUnsafeUnretained : TypeAttr {<br>
- let Spellings = [Keyword<"__unsafe_unretained">];<br>
- let Documentation = [Undocumented];<br>
-}<br>
-<br>
def ObjCKindOf : TypeAttr {<br>
let Spellings = [Keyword<"__kindof">];<br>
let Documentation = [Undocumented];<br>
@@ -1605,7 +1594,7 @@ def ObjCBridgeRelated : InheritableAttr<br>
let Documentation = [Undocumented];<br>
}<br>
<br>
-def NSReturnsRetained : DeclOrTypeAttr {<br>
+def NSReturnsRetained : InheritableAttr {<br>
let Spellings = [Clang<"ns_returns_retained">];<br>
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;<br>
let Documentation = [Undocumented];<br>
@@ -1790,8 +1779,6 @@ def Regparm : TypeAttr {<br>
let Spellings = [GCC<"regparm">];<br>
let Args = [UnsignedArgument<"NumParams">];<br>
let Documentation = [RegparmDocs];<br>
- // Represented as part of the enclosing function type.<br>
- let ASTNode = 0;<br>
}<br>
<br>
def ReqdWorkGroupSize : InheritableAttr {<br>
@@ -2080,9 +2067,10 @@ def ObjCGC : TypeAttr {<br>
let Documentation = [Undocumented];<br>
}<br>
<br>
-def ObjCOwnership : DeclOrTypeAttr {<br>
+def ObjCOwnership : InheritableAttr {<br>
let Spellings = [Clang<"objc_ownership">];<br>
let Args = [IdentifierArgument<"Kind">];<br>
+ let ASTNode = 0;<br>
let Documentation = [Undocumented];<br>
}<br>
<br>
@@ -2120,8 +2108,6 @@ def VectorSize : TypeAttr {<br>
let Spellings = [GCC<"vector_size">];<br>
let Args = [ExprArgument<"NumBytes">];<br>
let Documentation = [Undocumented];<br>
- // Represented as VectorType instead.<br>
- let ASTNode = 0;<br>
}<br>
<br>
def VecTypeHint : InheritableAttr {<br>
@@ -2216,7 +2202,7 @@ def AnyX86NoCallerSavedRegisters : Inher<br>
let Documentation = [AnyX86NoCallerSavedRegistersDocs];<br>
}<br>
<br>
-def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86>{<br>
+def AnyX86NoCfCheck : InheritableAttr, TargetSpecificAttr<TargetAnyX86>{<br>
let Spellings = [GCC<"nocf_check">];<br>
let Subjects = SubjectList<[FunctionLike]>;<br>
let Documentation = [AnyX86NoCfCheckDocs];<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Aug 13 18:55:37 2018<br>
@@ -1435,6 +1435,8 @@ public:<br>
<br>
TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);<br>
TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);<br>
+ TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,<br>
+ TypeSourceInfo *ReturnTypeInfo);<br>
<br>
/// Package the given type and TSI into a ParsedType.<br>
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo);<br>
@@ -3376,6 +3378,30 @@ public:<br>
/// Valid types should not have multiple attributes with different CCs.<br>
const AttributedType *getCallingConvAttributedType(QualType T) const;<br>
<br>
+ /// Check whether a nullability type specifier can be added to the given<br>
+ /// type.<br>
+ ///<br>
+ /// \param type The type to which the nullability specifier will be<br>
+ /// added. On success, this type will be updated appropriately.<br>
+ ///<br>
+ /// \param nullability The nullability specifier to add.<br>
+ ///<br>
+ /// \param nullabilityLoc The location of the nullability specifier.<br>
+ ///<br>
+ /// \param isContextSensitive Whether this nullability specifier was<br>
+ /// written as a context-sensitive keyword (in an Objective-C<br>
+ /// method) or an Objective-C property attribute, rather than as an<br>
+ /// underscored type specifier.<br>
+ ///<br>
+ /// \param allowArrayTypes Whether to accept nullability specifiers on an<br>
+ /// array type (e.g., because it will decay to a pointer).<br>
+ ///<br>
+ /// \returns true if nullability cannot be applied, false otherwise.<br>
+ bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind nullability,<br>
+ SourceLocation nullabilityLoc,<br>
+ bool isContextSensitive,<br>
+ bool allowArrayTypes);<br>
+<br>
/// Stmt attributes - this routine is the top level dispatcher.<br>
StmtResult ProcessStmtAttributes(Stmt *Stmt,<br>
const ParsedAttributesView &Attrs,<br>
@@ -8045,6 +8071,10 @@ public:<br>
SourceLocation ProtocolRAngleLoc,<br>
bool FailOnError = false);<br>
<br>
+ /// Check the application of the Objective-C '__kindof' qualifier to<br>
+ /// the given type.<br>
+ bool checkObjCKindOfType(QualType &type, SourceLocation loc);<br>
+<br>
/// Ensure attributes are consistent with type.<br>
/// \param [in, out] Attributes The attributes to check; they will<br>
/// be modified to be consistent with \p PropertyTy.<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Aug 13 18:55:37 2018<br>
@@ -2245,9 +2245,6 @@ public:<br>
CXXTemporary *ReadCXXTemporary(ModuleFile &F, const RecordData &Record,<br>
unsigned &Idx);<br>
<br>
- /// Reads one attribute from the current stream position.<br>
- Attr *ReadAttr(ModuleFile &M, const RecordData &Record, unsigned &Idx);<br>
-<br>
/// Reads attributes from the current stream position.<br>
void ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs);<br>
<br>
@@ -2633,11 +2630,6 @@ public:<br>
return ASTReader::ReadVersionTuple(Record, Idx);<br>
}<br>
<br>
- /// Reads one attribute from the current stream position, advancing Idx.<br>
- Attr *readAttr() {<br>
- return Reader->ReadAttr(*F, Record, Idx);<br>
- }<br>
-<br>
/// Reads attributes from the current stream position, advancing Idx.<br>
void readAttributes(AttrVec &Attrs) {<br>
return Reader->ReadAttributes(*this, Attrs);<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Mon Aug 13 18:55:37 2018<br>
@@ -955,9 +955,6 @@ public:<br>
return Writer->AddVersionTuple(Version, *Record);<br>
}<br>
<br>
- // Emit an attribute.<br>
- void AddAttr(const Attr *A);<br>
-<br>
/// Emit a list of attributes.<br>
void AddAttributes(ArrayRef<const Attr*> Attrs);<br>
};<br>
<br>
Modified: cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp (original)<br>
+++ cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp Mon Aug 13 18:55:37 2018<br>
@@ -81,11 +81,10 @@ public:<br>
}<br>
<br>
bool handleAttr(AttributedTypeLoc TL, Decl *D = nullptr) {<br>
- auto *OwnershipAttr = TL.getAttrAs<ObjCOwnershipAttr>();<br>
- if (!OwnershipAttr)<br>
+ if (TL.getAttrKind() != AttributedType::attr_objc_ownership)<br>
return false;<br>
<br>
- SourceLocation Loc = OwnershipAttr->getLocation();<br>
+ SourceLocation Loc = TL.getAttrNameLoc();<br>
unsigned RawLoc = Loc.getRawEncoding();<br>
if (MigrateCtx.AttrSet.count(RawLoc))<br>
return true;<br>
@@ -94,7 +93,13 @@ public:<br>
SourceManager &SM = Ctx.getSourceManager();<br>
if (Loc.isMacroID())<br>
Loc = SM.getImmediateExpansionRange(Loc).getBegin();<br>
- StringRef Spell = OwnershipAttr->getKind()->getName();<br>
+ SmallString<32> Buf;<br>
+ bool Invalid = false;<br>
+ StringRef Spell = Lexer::getSpelling(<br>
+ SM.getSpellingLoc(TL.getAttrEnumOperandLoc()),<br>
+ Buf, SM, Ctx.getLangOpts(), &Invalid);<br>
+ if (Invalid)<br>
+ return false;<br>
MigrationContext::GCAttrOccurrence::AttrKind Kind;<br>
if (Spell == "strong")<br>
Kind = MigrationContext::GCAttrOccurrence::Strong;<br>
@@ -279,7 +284,7 @@ static void checkAllAtProps(MigrationCon<br>
}<br>
<br>
for (unsigned i = 0, e = ATLs.size(); i != e; ++i) {<br>
- SourceLocation Loc = ATLs[i].first.getAttr()->getLocation();<br>
+ SourceLocation Loc = ATLs[i].first.getAttrNameLoc();<br>
if (Loc.isMacroID())<br>
Loc = MigrateCtx.Pass.Ctx.getSourceManager()<br>
.getImmediateExpansionRange(Loc)<br>
<br>
Modified: cfe/trunk/lib/ARCMigrate/Transforms.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/ARCMigrate/Transforms.cpp (original)<br>
+++ cfe/trunk/lib/ARCMigrate/Transforms.cpp Mon Aug 13 18:55:37 2018<br>
@@ -359,7 +359,7 @@ MigrationContext::~MigrationContext() {<br>
bool MigrationContext::isGCOwnedNonObjC(QualType T) {<br>
while (!T.isNull()) {<br>
if (const AttributedType *AttrT = T->getAs<AttributedType>()) {<br>
- if (AttrT->getAttrKind() == attr::ObjCOwnership)<br>
+ if (AttrT->getAttrKind() == AttributedType::attr_objc_ownership)<br>
return !AttrT->getModifiedType()->isObjCRetainableType();<br>
}<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/ASTContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ASTContext.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Aug 13 18:55:37 2018<br>
@@ -3876,7 +3876,7 @@ QualType ASTContext::getEnumType(const E<br>
return QualType(newType, 0);<br>
}<br>
<br>
-QualType ASTContext::getAttributedType(attr::Kind attrKind,<br>
+QualType ASTContext::getAttributedType(AttributedType::Kind attrKind,<br>
QualType modifiedType,<br>
QualType equivalentType) {<br>
llvm::FoldingSetNodeID id;<br>
<br>
Modified: cfe/trunk/lib/AST/Type.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/Type.cpp (original)<br>
+++ cfe/trunk/lib/AST/Type.cpp Mon Aug 13 18:55:37 2018<br>
@@ -592,6 +592,28 @@ bool Type::isObjCClassOrClassKindOfType(<br>
return OPT->isObjCClassType() || OPT->isObjCQualifiedClassType();<br>
}<br>
<br>
+/// Was this type written with the special inert-in-MRC __unsafe_unretained<br>
+/// qualifier?<br>
+///<br>
+/// This approximates the answer to the following question: if this<br>
+/// translation unit were compiled in ARC, would this type be qualified<br>
+/// with __unsafe_unretained?<br>
+bool Type::isObjCInertUnsafeUnretainedType() const {<br>
+ const Type *cur = this;<br>
+ while (true) {<br>
+ if (const auto attributed = dyn_cast<AttributedType>(cur)) {<br>
+ if (attributed->getAttrKind() ==<br>
+ AttributedType::attr_objc_inert_unsafe_unretained)<br>
+ return true;<br>
+ }<br>
+<br>
+ // Single-step desugar until we run out of sugar.<br>
+ QualType next = cur->getLocallyUnqualifiedSingleStepDesugaredType();<br>
+ if (next.getTypePtr() == cur) return false;<br>
+ cur = next.getTypePtr();<br>
+ }<br>
+}<br>
+<br>
ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D,<br>
QualType can,<br>
ArrayRef<ObjCProtocolDecl *> protocols)<br>
@@ -1619,16 +1641,6 @@ TagDecl *Type::getAsTagDecl() const {<br>
return nullptr;<br>
}<br>
<br>
-bool Type::hasAttr(attr::Kind AK) const {<br>
- const Type *Cur = this;<br>
- while (const auto *AT = Cur->getAs<AttributedType>()) {<br>
- if (AT->getAttrKind() == AK)<br>
- return true;<br>
- Cur = AT->getEquivalentType().getTypePtr();<br>
- }<br>
- return false;<br>
-}<br>
-<br>
namespace {<br>
<br>
class GetContainedDeducedTypeVisitor :<br>
@@ -3155,58 +3167,105 @@ bool RecordType::hasConstFields() const<br>
}<br>
<br>
bool AttributedType::isQualifier() const {<br>
- // FIXME: Generate this with TableGen.<br>
switch (getAttrKind()) {<br>
// These are type qualifiers in the traditional C sense: they annotate<br>
// something about a specific value/variable of a type. (They aren't<br>
// always part of the canonical type, though.)<br>
- case attr::ObjCGC:<br>
- case attr::ObjCOwnership:<br>
- case attr::ObjCInertUnsafeUnretained:<br>
- case attr::TypeNonNull:<br>
- case attr::TypeNullable:<br>
- case attr::TypeNullUnspecified:<br>
- case attr::LifetimeBound:<br>
- return true;<br>
-<br>
- // All other type attributes aren't qualifiers; they rewrite the modified<br>
- // type to be a semantically different type.<br>
- default:<br>
+ case AttributedType::attr_address_space:<br>
+ case AttributedType::attr_objc_gc:<br>
+ case AttributedType::attr_objc_ownership:<br>
+ case AttributedType::attr_objc_inert_unsafe_unretained:<br>
+ case AttributedType::attr_nonnull:<br>
+ case AttributedType::attr_nullable:<br>
+ case AttributedType::attr_null_unspecified:<br>
+ case AttributedType::attr_lifetimebound:<br>
+ return true;<br>
+<br>
+ // These aren't qualifiers; they rewrite the modified type to be a<br>
+ // semantically different type.<br>
+ case AttributedType::attr_regparm:<br>
+ case AttributedType::attr_vector_size:<br>
+ case AttributedType::attr_neon_vector_type:<br>
+ case AttributedType::attr_neon_polyvector_type:<br>
+ case AttributedType::attr_pcs:<br>
+ case AttributedType::attr_pcs_vfp:<br>
+ case AttributedType::attr_noreturn:<br>
+ case AttributedType::attr_cdecl:<br>
+ case AttributedType::attr_fastcall:<br>
+ case AttributedType::attr_stdcall:<br>
+ case AttributedType::attr_thiscall:<br>
+ case AttributedType::attr_regcall:<br>
+ case AttributedType::attr_pascal:<br>
+ case AttributedType::attr_swiftcall:<br>
+ case AttributedType::attr_vectorcall:<br>
+ case AttributedType::attr_inteloclbicc:<br>
+ case AttributedType::attr_preserve_most:<br>
+ case AttributedType::attr_preserve_all:<br>
+ case AttributedType::attr_ms_abi:<br>
+ case AttributedType::attr_sysv_abi:<br>
+ case AttributedType::attr_ptr32:<br>
+ case AttributedType::attr_ptr64:<br>
+ case AttributedType::attr_sptr:<br>
+ case AttributedType::attr_uptr:<br>
+ case AttributedType::attr_objc_kindof:<br>
+ case AttributedType::attr_ns_returns_retained:<br>
+ case AttributedType::attr_nocf_check:<br>
return false;<br>
}<br>
+ llvm_unreachable("bad attributed type kind");<br>
}<br>
<br>
bool AttributedType::isMSTypeSpec() const {<br>
- // FIXME: Generate this with TableGen?<br>
switch (getAttrKind()) {<br>
- default: return false;<br>
- case attr::Ptr32:<br>
- case attr::Ptr64:<br>
- case attr::SPtr:<br>
- case attr::UPtr:<br>
+ default: return false;<br>
+ case attr_ptr32:<br>
+ case attr_ptr64:<br>
+ case attr_sptr:<br>
+ case attr_uptr:<br>
return true;<br>
}<br>
llvm_unreachable("invalid attr kind");<br>
}<br>
<br>
bool AttributedType::isCallingConv() const {<br>
- // FIXME: Generate this with TableGen.<br>
switch (getAttrKind()) {<br>
- default: return false;<br>
- case attr::Pcs:<br>
- case attr::CDecl:<br>
- case attr::FastCall:<br>
- case attr::StdCall:<br>
- case attr::ThisCall:<br>
- case attr::RegCall:<br>
- case attr::SwiftCall:<br>
- case attr::VectorCall:<br>
- case attr::Pascal:<br>
- case attr::MSABI:<br>
- case attr::SysVABI:<br>
- case attr::IntelOclBicc:<br>
- case attr::PreserveMost:<br>
- case attr::PreserveAll:<br>
+ case attr_ptr32:<br>
+ case attr_ptr64:<br>
+ case attr_sptr:<br>
+ case attr_uptr:<br>
+ case attr_address_space:<br>
+ case attr_regparm:<br>
+ case attr_vector_size:<br>
+ case attr_neon_vector_type:<br>
+ case attr_neon_polyvector_type:<br>
+ case attr_objc_gc:<br>
+ case attr_objc_ownership:<br>
+ case attr_objc_inert_unsafe_unretained:<br>
+ case attr_noreturn:<br>
+ case attr_nonnull:<br>
+ case attr_ns_returns_retained:<br>
+ case attr_nullable:<br>
+ case attr_null_unspecified:<br>
+ case attr_objc_kindof:<br>
+ case attr_nocf_check:<br>
+ case attr_lifetimebound:<br>
+ return false;<br>
+<br>
+ case attr_pcs:<br>
+ case attr_pcs_vfp:<br>
+ case attr_cdecl:<br>
+ case attr_fastcall:<br>
+ case attr_stdcall:<br>
+ case attr_thiscall:<br>
+ case attr_regcall:<br>
+ case attr_swiftcall:<br>
+ case attr_vectorcall:<br>
+ case attr_pascal:<br>
+ case attr_ms_abi:<br>
+ case attr_sysv_abi:<br>
+ case attr_inteloclbicc:<br>
+ case attr_preserve_most:<br>
+ case attr_preserve_all:<br>
return true;<br>
}<br>
llvm_unreachable("invalid attr kind");<br>
@@ -3649,18 +3708,23 @@ LinkageInfo Type::getLinkageAndVisibilit<br>
return LinkageComputer{}.getTypeLinkageAndVisibility(this);<br>
}<br>
<br>
-Optional<NullabilityKind><br>
-Type::getNullability(const ASTContext &Context) const {<br>
- QualType Type(this, 0);<br>
- while (const auto *AT = Type->getAs<AttributedType>()) {<br>
+Optional<NullabilityKind> Type::getNullability(const ASTContext &context) const {<br>
+ QualType type(this, 0);<br>
+ do {<br>
// Check whether this is an attributed type with nullability<br>
// information.<br>
- if (auto Nullability = AT->getImmediateNullability())<br>
- return Nullability;<br>
+ if (auto attributed = dyn_cast<AttributedType>(type.getTypePtr())) {<br>
+ if (auto nullability = attributed->getImmediateNullability())<br>
+ return nullability;<br>
+ }<br>
<br>
- Type = AT->getEquivalentType();<br>
- }<br>
- return None;<br>
+ // Desugar the type. If desugaring does nothing, we're done.<br>
+ QualType desugared = type.getSingleStepDesugaredType(context);<br>
+ if (desugared.getTypePtr() == type.getTypePtr())<br>
+ return None;<br>
+<br>
+ type = desugared;<br>
+ } while (true);<br>
}<br>
<br>
bool Type::canHaveNullability(bool ResultIfUnknown) const {<br>
@@ -3773,13 +3837,12 @@ bool Type::canHaveNullability(bool Resul<br>
llvm_unreachable("bad type kind!");<br>
}<br>
<br>
-llvm::Optional<NullabilityKind><br>
-AttributedType::getImmediateNullability() const {<br>
- if (getAttrKind() == attr::TypeNonNull)<br>
+llvm::Optional<NullabilityKind> AttributedType::getImmediateNullability() const {<br>
+ if (getAttrKind() == AttributedType::attr_nonnull)<br>
return NullabilityKind::NonNull;<br>
- if (getAttrKind() == attr::TypeNullable)<br>
+ if (getAttrKind() == AttributedType::attr_nullable)<br>
return NullabilityKind::Nullable;<br>
- if (getAttrKind() == attr::TypeNullUnspecified)<br>
+ if (getAttrKind() == AttributedType::attr_null_unspecified)<br>
return NullabilityKind::Unspecified;<br>
return None;<br>
}<br>
<br>
Modified: cfe/trunk/lib/AST/TypeLoc.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLoc.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLoc.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/TypeLoc.cpp (original)<br>
+++ cfe/trunk/lib/AST/TypeLoc.cpp Mon Aug 13 18:55:37 2018<br>
@@ -404,11 +404,11 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLo<br>
}<br>
<br>
SourceLocation TypeLoc::findNullabilityLoc() const {<br>
- if (auto ATL = getAs<AttributedTypeLoc>()) {<br>
- const Attr *A = ATL.getAttr();<br>
- if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) ||<br>
- isa<TypeNullUnspecifiedAttr>(A)))<br>
- return A->getLocation();<br>
+ if (auto attributedLoc = getAs<AttributedTypeLoc>()) {<br>
+ if (attributedLoc.getAttrKind() == AttributedType::attr_nullable ||<br>
+ attributedLoc.getAttrKind() == AttributedType::attr_nonnull ||<br>
+ attributedLoc.getAttrKind() == AttributedType::attr_null_unspecified)<br>
+ return attributedLoc.getAttrNameLoc();<br>
}<br>
<br>
return {};<br>
<br>
Modified: cfe/trunk/lib/AST/TypePrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/TypePrinter.cpp Mon Aug 13 18:55:37 2018<br>
@@ -1354,14 +1354,12 @@ void TypePrinter::printPackExpansionAfte<br>
<br>
void TypePrinter::printAttributedBefore(const AttributedType *T,<br>
raw_ostream &OS) {<br>
- // FIXME: Generate this with TableGen.<br>
-<br>
// Prefer the macro forms of the GC and ownership qualifiers.<br>
- if (T->getAttrKind() == attr::ObjCGC ||<br>
- T->getAttrKind() == attr::ObjCOwnership)<br>
+ if (T->getAttrKind() == AttributedType::attr_objc_gc ||<br>
+ T->getAttrKind() == AttributedType::attr_objc_ownership)<br>
return printBefore(T->getEquivalentType(), OS);<br>
<br>
- if (T->getAttrKind() == attr::ObjCKindOf)<br>
+ if (T->getAttrKind() == AttributedType::attr_objc_kindof)<br>
OS << "__kindof ";<br>
<br>
printBefore(T->getModifiedType(), OS);<br>
@@ -1369,21 +1367,23 @@ void TypePrinter::printAttributedBefore(<br>
if (T->isMSTypeSpec()) {<br>
switch (T->getAttrKind()) {<br>
default: return;<br>
- case attr::Ptr32: OS << " __ptr32"; break;<br>
- case attr::Ptr64: OS << " __ptr64"; break;<br>
- case attr::SPtr: OS << " __sptr"; break;<br>
- case attr::UPtr: OS << " __uptr"; break;<br>
+ case AttributedType::attr_ptr32: OS << " __ptr32"; break;<br>
+ case AttributedType::attr_ptr64: OS << " __ptr64"; break;<br>
+ case AttributedType::attr_sptr: OS << " __sptr"; break;<br>
+ case AttributedType::attr_uptr: OS << " __uptr"; break;<br>
}<br>
spaceBeforePlaceHolder(OS);<br>
}<br>
<br>
// Print nullability type specifiers.<br>
- if (T->getImmediateNullability()) {<br>
- if (T->getAttrKind() == attr::TypeNonNull)<br>
+ if (T->getAttrKind() == AttributedType::attr_nonnull ||<br>
+ T->getAttrKind() == AttributedType::attr_nullable ||<br>
+ T->getAttrKind() == AttributedType::attr_null_unspecified) {<br>
+ if (T->getAttrKind() == AttributedType::attr_nonnull)<br>
OS << " _Nonnull";<br>
- else if (T->getAttrKind() == attr::TypeNullable)<br>
+ else if (T->getAttrKind() == AttributedType::attr_nullable)<br>
OS << " _Nullable";<br>
- else if (T->getAttrKind() == attr::TypeNullUnspecified)<br>
+ else if (T->getAttrKind() == AttributedType::attr_null_unspecified)<br>
OS << " _Null_unspecified";<br>
else<br>
llvm_unreachable("unhandled nullability");<br>
@@ -1393,11 +1393,9 @@ void TypePrinter::printAttributedBefore(<br>
<br>
void TypePrinter::printAttributedAfter(const AttributedType *T,<br>
raw_ostream &OS) {<br>
- // FIXME: Generate this with TableGen.<br>
-<br>
// Prefer the macro forms of the GC and ownership qualifiers.<br>
- if (T->getAttrKind() == attr::ObjCGC ||<br>
- T->getAttrKind() == attr::ObjCOwnership)<br>
+ if (T->getAttrKind() == AttributedType::attr_objc_gc ||<br>
+ T->getAttrKind() == AttributedType::attr_objc_ownership)<br>
return printAfter(T->getEquivalentType(), OS);<br>
<br>
// If this is a calling convention attribute, don't print the implicit CC from<br>
@@ -1408,74 +1406,107 @@ void TypePrinter::printAttributedAfter(c<br>
<br>
// Some attributes are printed as qualifiers before the type, so we have<br>
// nothing left to do.<br>
- if (T->getAttrKind() == attr::ObjCKindOf ||<br>
- T->isMSTypeSpec() || T->getImmediateNullability())<br>
+ if (T->getAttrKind() == AttributedType::attr_objc_kindof ||<br>
+ T->isMSTypeSpec() ||<br>
+ T->getAttrKind() == AttributedType::attr_nonnull ||<br>
+ T->getAttrKind() == AttributedType::attr_nullable ||<br>
+ T->getAttrKind() == AttributedType::attr_null_unspecified)<br>
return;<br>
<br>
// Don't print the inert __unsafe_unretained attribute at all.<br>
- if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)<br>
+ if (T->getAttrKind() == AttributedType::attr_objc_inert_unsafe_unretained)<br>
return;<br>
<br>
// Don't print ns_returns_retained unless it had an effect.<br>
- if (T->getAttrKind() == attr::NSReturnsRetained &&<br>
+ if (T->getAttrKind() == AttributedType::attr_ns_returns_retained &&<br>
!T->getEquivalentType()->castAs<FunctionType>()<br>
->getExtInfo().getProducesResult())<br>
return;<br>
<br>
- if (T->getAttrKind() == attr::LifetimeBound) {<br>
+ if (T->getAttrKind() == AttributedType::attr_lifetimebound) {<br>
OS << " [[clang::lifetimebound]]";<br>
return;<br>
}<br>
<br>
OS << " __attribute__((";<br>
switch (T->getAttrKind()) {<br>
-#define TYPE_ATTR(NAME)<br>
-#define DECL_OR_TYPE_ATTR(NAME)<br>
-#define ATTR(NAME) case attr::NAME:<br>
-#include "clang/Basic/AttrList.inc"<br>
- llvm_unreachable("non-type attribute attached to type");<br>
-<br>
- case attr::OpenCLPrivateAddressSpace:<br>
- case attr::OpenCLGlobalAddressSpace:<br>
- case attr::OpenCLLocalAddressSpace:<br>
- case attr::OpenCLConstantAddressSpace:<br>
- case attr::OpenCLGenericAddressSpace:<br>
- // FIXME: Update printAttributedBefore to print these once we generate<br>
- // AttributedType nodes for them.<br>
- break;<br>
-<br>
- case attr::LifetimeBound:<br>
- case attr::TypeNonNull:<br>
- case attr::TypeNullable:<br>
- case attr::TypeNullUnspecified:<br>
- case attr::ObjCGC:<br>
- case attr::ObjCInertUnsafeUnretained:<br>
- case attr::ObjCKindOf:<br>
- case attr::ObjCOwnership:<br>
- case attr::Ptr32:<br>
- case attr::Ptr64:<br>
- case attr::SPtr:<br>
- case attr::UPtr:<br>
+ case AttributedType::attr_lifetimebound:<br>
+ case AttributedType::attr_nonnull:<br>
+ case AttributedType::attr_nullable:<br>
+ case AttributedType::attr_null_unspecified:<br>
+ case AttributedType::attr_objc_gc:<br>
+ case AttributedType::attr_objc_inert_unsafe_unretained:<br>
+ case AttributedType::attr_objc_kindof:<br>
+ case AttributedType::attr_objc_ownership:<br>
+ case AttributedType::attr_ptr32:<br>
+ case AttributedType::attr_ptr64:<br>
+ case AttributedType::attr_sptr:<br>
+ case AttributedType::attr_uptr:<br>
llvm_unreachable("This attribute should have been handled already");<br>
<br>
- case attr::NSReturnsRetained:<br>
+ case AttributedType::attr_address_space:<br>
+ OS << "address_space(";<br>
+ // FIXME: printing the raw LangAS value is wrong. This should probably<br>
+ // use the same code as Qualifiers::print()<br>
+ OS << (unsigned)T->getEquivalentType().getAddressSpace();<br>
+ OS << ')';<br>
+ break;<br>
+<br>
+ case AttributedType::attr_vector_size:<br>
+ OS << "__vector_size__(";<br>
+ if (const auto *vector = T->getEquivalentType()->getAs<VectorType>()) {<br>
+ OS << vector->getNumElements();<br>
+ OS << " * sizeof(";<br>
+ print(vector->getElementType(), OS, StringRef());<br>
+ OS << ')';<br>
+ }<br>
+ OS << ')';<br>
+ break;<br>
+<br>
+ case AttributedType::attr_neon_vector_type:<br>
+ case AttributedType::attr_neon_polyvector_type: {<br>
+ if (T->getAttrKind() == AttributedType::attr_neon_vector_type)<br>
+ OS << "neon_vector_type(";<br>
+ else<br>
+ OS << "neon_polyvector_type(";<br>
+ const auto *vector = T->getEquivalentType()->getAs<VectorType>();<br>
+ OS << vector->getNumElements();<br>
+ OS << ')';<br>
+ break;<br>
+ }<br>
+<br>
+ case AttributedType::attr_regparm: {<br>
+ // FIXME: When Sema learns to form this AttributedType, avoid printing the<br>
+ // attribute again in printFunctionProtoAfter.<br>
+ OS << "regparm(";<br>
+ QualType t = T->getEquivalentType();<br>
+ while (!t->isFunctionType())<br>
+ t = t->getPointeeType();<br>
+ OS << t->getAs<FunctionType>()->getRegParmType();<br>
+ OS << ')';<br>
+ break;<br>
+ }<br>
+<br>
+ case AttributedType::attr_ns_returns_retained:<br>
OS << "ns_returns_retained";<br>
break;<br>
<br>
// FIXME: When Sema learns to form this AttributedType, avoid printing the<br>
// attribute again in printFunctionProtoAfter.<br>
- case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;<br>
- case attr::CDecl: OS << "cdecl"; break;<br>
- case attr::FastCall: OS << "fastcall"; break;<br>
- case attr::StdCall: OS << "stdcall"; break;<br>
- case attr::ThisCall: OS << "thiscall"; break;<br>
- case attr::SwiftCall: OS << "swiftcall"; break;<br>
- case attr::VectorCall: OS << "vectorcall"; break;<br>
- case attr::Pascal: OS << "pascal"; break;<br>
- case attr::MSABI: OS << "ms_abi"; break;<br>
- case attr::SysVABI: OS << "sysv_abi"; break;<br>
- case attr::RegCall: OS << "regcall"; break;<br>
- case attr::Pcs: {<br>
+ case AttributedType::attr_noreturn: OS << "noreturn"; break;<br>
+ case AttributedType::attr_nocf_check: OS << "nocf_check"; break;<br>
+ case AttributedType::attr_cdecl: OS << "cdecl"; break;<br>
+ case AttributedType::attr_fastcall: OS << "fastcall"; break;<br>
+ case AttributedType::attr_stdcall: OS << "stdcall"; break;<br>
+ case AttributedType::attr_thiscall: OS << "thiscall"; break;<br>
+ case AttributedType::attr_swiftcall: OS << "swiftcall"; break;<br>
+ case AttributedType::attr_vectorcall: OS << "vectorcall"; break;<br>
+ case AttributedType::attr_pascal: OS << "pascal"; break;<br>
+ case AttributedType::attr_ms_abi: OS << "ms_abi"; break;<br>
+ case AttributedType::attr_sysv_abi: OS << "sysv_abi"; break;<br>
+ case AttributedType::attr_regcall: OS << "regcall"; break;<br>
+ case AttributedType::attr_pcs:<br>
+ case AttributedType::attr_pcs_vfp: {<br>
OS << "pcs(";<br>
QualType t = T->getEquivalentType();<br>
while (!t->isFunctionType())<br>
@@ -1486,12 +1517,12 @@ void TypePrinter::printAttributedAfter(c<br>
break;<br>
}<br>
<br>
- case attr::IntelOclBicc: OS << "inteloclbicc"; break;<br>
- case attr::PreserveMost:<br>
+ case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break;<br>
+ case AttributedType::attr_preserve_most:<br>
OS << "preserve_most";<br>
break;<br>
<br>
- case attr::PreserveAll:<br>
+ case AttributedType::attr_preserve_all:<br>
OS << "preserve_all";<br>
break;<br>
}<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Aug 13 18:55:37 2018<br>
@@ -5999,14 +5999,14 @@ static void checkAttributesAfterMerging(<br>
// The [[lifetimebound]] attribute can be applied to the implicit object<br>
// parameter of a non-static member function (other than a ctor or dtor)<br>
// by applying it to the function type.<br>
- if (const auto *A = ATL.getAttrAs<LifetimeBoundAttr>()) {<br>
+ if (ATL.getAttrKind() == AttributedType::attr_lifetimebound) {<br>
const auto *MD = dyn_cast<CXXMethodDecl>(FD);<br>
if (!MD || MD->isStatic()) {<br>
- S.Diag(A->getLocation(), diag::err_lifetimebound_no_object_param)<br>
- << !MD << A->getRange();<br>
+ S.Diag(ATL.getAttrNameLoc(), diag::err_lifetimebound_no_object_param)<br>
+ << !MD << ATL.getLocalSourceRange();<br>
} else if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) {<br>
- S.Diag(A->getLocation(), diag::err_lifetimebound_ctor_dtor)<br>
- << isa<CXXDestructorDecl>(MD) << A->getRange();<br>
+ S.Diag(ATL.getAttrNameLoc(), diag::err_lifetimebound_ctor_dtor)<br>
+ << isa<CXXDestructorDecl>(MD) << ATL.getLocalSourceRange();<br>
}<br>
}<br>
}<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Aug 13 18:55:37 2018<br>
@@ -14658,15 +14658,15 @@ static bool captureInBlock(BlockScopeInf<br>
// Warn about implicitly autoreleasing indirect parameters captured by blocks.<br>
if (const auto *PT = CaptureType->getAs<PointerType>()) {<br>
// This function finds out whether there is an AttributedType of kind<br>
- // attr::ObjCOwnership in Ty. The existence of AttributedType of kind<br>
- // attr::ObjCOwnership implies __autoreleasing was explicitly specified<br>
+ // attr_objc_ownership in Ty. The existence of AttributedType of kind<br>
+ // attr_objc_ownership implies __autoreleasing was explicitly specified<br>
// rather than being added implicitly by the compiler.<br>
auto IsObjCOwnershipAttributedType = [](QualType Ty) {<br>
while (const auto *AttrTy = Ty->getAs<AttributedType>()) {<br>
- if (AttrTy->getAttrKind() == attr::ObjCOwnership)<br>
+ if (AttrTy->getAttrKind() == AttributedType::attr_objc_ownership)<br>
return true;<br>
<br>
- // Peel off AttributedTypes that are not of kind ObjCOwnership.<br>
+ // Peel off AttributedTypes that are not of kind objc_ownership.<br>
Ty = AttrTy->getModifiedType();<br>
}<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Aug 13 18:55:37 2018<br>
@@ -6360,7 +6360,7 @@ static bool implicitObjectParamIsLifetim<br>
for (TypeLoc TL = TSI->getTypeLoc();<br>
(ATL = TL.getAsAdjusted<AttributedTypeLoc>());<br>
TL = ATL.getModifiedLoc()) {<br>
- if (ATL.getAttrAs<LifetimeBoundAttr>())<br>
+ if (ATL.getAttrKind() == AttributedType::attr_lifetimebound)<br>
return true;<br>
}<br>
return false;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Mon Aug 13 18:55:37 2018<br>
@@ -2384,7 +2384,7 @@ void Sema::ProcessPropertyDecl(ObjCPrope<br>
QualType modifiedTy = resultTy;<br>
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {<br>
if (*nullability == NullabilityKind::Unspecified)<br>
- resultTy = Context.getAttributedType(attr::TypeNonNull,<br>
+ resultTy = Context.getAttributedType(AttributedType::attr_nonnull,<br>
modifiedTy, modifiedTy);<br>
}<br>
}<br>
@@ -2458,7 +2458,7 @@ void Sema::ProcessPropertyDecl(ObjCPrope<br>
QualType modifiedTy = paramTy;<br>
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){<br>
if (*nullability == NullabilityKind::Unspecified)<br>
- paramTy = Context.getAttributedType(attr::TypeNullable,<br>
+ paramTy = Context.getAttributedType(AttributedType::attr_nullable,<br>
modifiedTy, modifiedTy);<br>
}<br>
}<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaType.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=339638&r1=339637&r2=339638&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=339638&r1=339637&r2=339638&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaType.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Aug 13 18:55:37 2018<br>
@@ -172,16 +172,6 @@ namespace {<br>
/// processing is complete.<br>
SmallVector<ParsedAttr *, 2> ignoredTypeAttrs;<br>
<br>
- /// Attributes corresponding to AttributedTypeLocs that we have not yet<br>
- /// populated.<br>
- // FIXME: The two-phase mechanism by which we construct Types and fill<br>
- // their TypeLocs makes it hard to correctly assign these. We keep the<br>
- // attributes in creation order as an attempt to make them line up<br>
- // properly.<br>
- using TypeAttrPair = std::pair<const AttributedType*, const Attr*>;<br>
- SmallVector<TypeAttrPair, 8> AttrsForTypes;<br>
- bool AttrsForTypesSorted = true;<br>
-<br>
public:<br>
TypeProcessingState(Sema &sema, Declarator &declarator)<br>
: sema(sema), declarator(declarator),<br>
@@ -240,43 +230,6 @@ namespace {<br>
diagnoseBadTypeAttribute(getSema(), *Attr, type);<br>
}<br>
<br>
- /// Get an attributed type for the given attribute, and remember the Attr<br>
- /// object so that we can attach it to the AttributedTypeLoc.<br>
- QualType getAttributedType(Attr *A, QualType ModifiedType,<br>
- QualType EquivType) {<br>
- QualType T =<br>
- sema.Context.getAttributedType(A->getKind(), ModifiedType, EquivType);<br>
- AttrsForTypes.push_back({cast<AttributedType>(T.getTypePtr()), A});<br>
- AttrsForTypesSorted = false;<br>
- return T;<br>
- }<br>
-<br>
- /// Extract and remove the Attr* for a given attributed type.<br>
- const Attr *takeAttrForAttributedType(const AttributedType *AT) {<br>
- if (!AttrsForTypesSorted) {<br>
- std::stable_sort(AttrsForTypes.begin(), AttrsForTypes.end(),<br>
- [](const TypeAttrPair &A, const TypeAttrPair &B) {<br>
- return A.first < B.first;<br>
- });<br>
- AttrsForTypesSorted = true;<br>
- }<br>
-<br>
- // FIXME: This is quadratic if we have lots of reuses of the same<br>
- // attributed type.<br>
- for (auto It = std::partition_point(<br>
- AttrsForTypes.begin(), AttrsForTypes.end(),<br>
- [=](const TypeAttrPair &A) { return A.first < AT; });<br>
- It != AttrsForTypes.end() && It->first == AT; ++It) {<br>
- if (It->second) {<br>
- const Attr *Result = It->second;<br>
- It->second = nullptr;<br>
- return Result;<br>
- }<br>
- }<br>
-<br>
- llvm_unreachable("no Attr* for AttributedType*");<br>
- }<br>
-<br>
~TypeProcessingState() {<br>
if (trivial) return;<br>
<br>
@@ -3879,32 +3832,6 @@ static bool hasOuterPointerLikeChunk(con<br>
return false;<br>
}<br>
<br>
-template<typename AttrT><br>
-static AttrT *createSimpleAttr(ASTContext &Ctx, ParsedAttr &Attr) {<br>
- Attr.setUsedAsTypeAttr();<br>
- return ::new (Ctx)<br>
- AttrT(Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex());<br>
-}<br>
-<br>
-static Attr *createNullabilityAttr(ASTContext &Ctx, ParsedAttr &Attr,<br>
- NullabilityKind NK) {<br>
- switch (NK) {<br>
- case NullabilityKind::NonNull:<br>
- return createSimpleAttr<TypeNonNullAttr>(Ctx, Attr);<br>
-<br>
- case NullabilityKind::Nullable:<br>
- return createSimpleAttr<TypeNullableAttr>(Ctx, Attr);<br>
-<br>
- case NullabilityKind::Unspecified:<br>
- return createSimpleAttr<TypeNullUnspecifiedAttr>(Ctx, Attr);<br>
- }<br>
- llvm_unreachable("unknown NullabilityKind");<br>
-}<br>
-<br>
-static TypeSourceInfo *<br>
-GetTypeSourceInfoForDeclarator(TypeProcessingState &State,<br>
- QualType T, TypeSourceInfo *ReturnTypeInfo);<br>
-<br>
static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,<br>
QualType declSpecType,<br>
TypeSourceInfo *TInfo) {<br>
@@ -4257,8 +4184,9 @@ static TypeSourceInfo *GetFullTypeForDec<br>
pointerKind, D.getDeclSpec().getTypeSpecTypeLoc(),<br>
D.getDeclSpec().getEndLoc(),<br>
D.getMutableDeclSpec().getAttributes())) {<br>
- T = state.getAttributedType(<br>
- createNullabilityAttr(Context, *attr, *inferNullability), T, T);<br>
+ T = Context.getAttributedType(<br>
+ AttributedType::getNullabilityAttrKind(*inferNullability),T,T);<br>
+ attr->setUsedAsTypeAttr();<br>
}<br>
}<br>
}<br>
@@ -5097,7 +5025,7 @@ static TypeSourceInfo *GetFullTypeForDec<br>
if (D.isInvalidType())<br>
return Context.getTrivialTypeSourceInfo(T);<br>
<br>
- return GetTypeSourceInfoForDeclarator(state, T, TInfo);<br>
+ return S.GetTypeSourceInfoForDeclarator(D, T, TInfo);<br>
}<br>
<br>
/// GetTypeForDeclarator - Convert the type for the specified<br>
@@ -5233,25 +5161,131 @@ TypeSourceInfo *Sema::GetTypeForDeclarat<br>
return GetFullTypeForDeclarator(state, declSpecTy, ReturnTypeInfo);<br>
}<br>
<br>
+/// Map an AttributedType::Kind to an ParsedAttr::Kind.<br>
+static ParsedAttr::Kind getAttrListKind(AttributedType::Kind kind) {<br>
+ switch (kind) {<br>
+ case AttributedType::attr_address_space:<br>
+ return ParsedAttr::AT_AddressSpace;<br>
+ case AttributedType::attr_regparm:<br>
+ return ParsedAttr::AT_Regparm;<br>
+ case AttributedType::attr_vector_size:<br>
+ return ParsedAttr::AT_VectorSize;<br>
+ case AttributedType::attr_neon_vector_type:<br>
+ return ParsedAttr::AT_NeonVectorType;<br>
+ case AttributedType::attr_neon_polyvector_type:<br>
+ return ParsedAttr::AT_NeonPolyVectorType;<br>
+ case AttributedType::attr_objc_gc:<br>
+ return ParsedAttr::AT_ObjCGC;<br>
+ case AttributedType::attr_objc_ownership:<br>
+ case AttributedType::attr_objc_inert_unsafe_unretained:<br>
+ return ParsedAttr::AT_ObjCOwnership;<br>
+ case AttributedType::attr_noreturn:<br>
+ return ParsedAttr::AT_NoReturn;<br>
+ case AttributedType::attr_nocf_check:<br>
+ return ParsedAttr::AT_AnyX86NoCfCheck;<br>
+ case AttributedType::attr_cdecl:<br>
+ return ParsedAttr::AT_CDecl;<br>
+ case AttributedType::attr_fastcall:<br>
+ return ParsedAttr::AT_FastCall;<br>
+ case AttributedType::attr_stdcall:<br>
+ return ParsedAttr::AT_StdCall;<br>
+ case AttributedType::attr_thiscall:<br>
+ return ParsedAttr::AT_ThisCall;<br>
+ case AttributedType::attr_regcall:<br>
+ return ParsedAttr::AT_RegCall;<br>
+ case AttributedType::attr_pascal:<br>
+ return ParsedAttr::AT_Pascal;<br>
+ case AttributedType::attr_swiftcall:<br>
+ return ParsedAttr::AT_SwiftCall;<br>
+ case AttributedType::attr_vectorcall:<br>
+ return ParsedAttr::AT_VectorCall;<br>
+ case AttributedType::attr_pcs:<br>
+ case AttributedType::attr_pcs_vfp:<br>
+ return ParsedAttr::AT_Pcs;<br>
+ case AttributedType::attr_inteloclbicc:<br>
+ return ParsedAttr::AT_IntelOclBicc;<br>
+ case AttributedType::attr_ms_abi:<br>
+ return ParsedAttr::AT_MSABI;<br>
+ case AttributedType::attr_sysv_abi:<br>
+ return ParsedAttr::AT_SysVABI;<br>
+ case AttributedType::attr_preserve_most:<br>
+ return ParsedAttr::AT_PreserveMost;<br>
+ case AttributedType::attr_preserve_all:<br>
+ return ParsedAttr::AT_PreserveAll;<br>
+ case AttributedType::attr_ptr32:<br>
+ return ParsedAttr::AT_Ptr32;<br>
+ case AttributedType::attr_ptr64:<br>
+ return ParsedAttr::AT_Ptr64;<br>
+ case AttributedType::attr_sptr:<br>
+ return ParsedAttr::AT_SPtr;<br>
+ case AttributedType::attr_uptr:<br>
+ return ParsedAttr::AT_UPtr;<br>
+ case AttributedType::attr_nonnull:<br>
+ return ParsedAttr::AT_TypeNonNull;<br>
+ case AttributedType::attr_nullable:<br>
+ return ParsedAttr::AT_TypeNullable;<br>
+ case AttributedType::attr_null_unspecified:<br>
+ return ParsedAttr::AT_TypeNullUnspecified;<br>
+ case AttributedType::attr_objc_kindof:<br>
+ return ParsedAttr::AT_ObjCKindOf;<br>
+ case AttributedType::attr_ns_returns_retained:<br>
+ return ParsedAttr::AT_NSReturnsRetained;<br>
+ case AttributedType::attr_lifetimebound:<br>
+ return ParsedAttr::AT_LifetimeBound;<br>
+ }<br>
+ llvm_unreachable("unexpected attribute kind!");<br>
+}<br>
+<br>
+static void setAttributedTypeLoc(AttributedTypeLoc TL, const ParsedAttr &attr) {<br>
+ TL.setAttrNameLoc(attr.getLoc());<br>
+ if (TL.hasAttrExprOperand()) {<br>
+ assert(attr.isArgExpr(0) && "mismatched attribute operand kind");<br>
+ TL.setAttrExprOperand(attr.getArgAsExpr(0));<br>
+ } else if (TL.hasAttrEnumOperand()) {<br>
+ assert((attr.isArgIdent(0) || attr.isArgExpr(0)) &&<br>
+ "unexpected attribute operand kind");<br>
+ if (attr.isArgIdent(0))<br>
+ TL.setAttrEnumOperandLoc(attr.getArgAsIdent(0)->Loc);<br>
+ else<br>
+ TL.setAttrEnumOperandLoc(attr.getArgAsExpr(0)->getExprLoc());<br>
+ }<br>
+<br>
+ // FIXME: preserve this information to here.<br>
+ if (TL.hasAttrOperand())<br>
+ TL.setAttrOperandParensRange(SourceRange());<br>
+}<br>
+<br>
static void fillAttributedTypeLoc(AttributedTypeLoc TL,<br>
- TypeProcessingState &State) {<br>
- TL.setAttr(State.takeAttrForAttributedType(TL.getTypePtr()));<br>
+ const ParsedAttributesView &Attrs,<br>
+ const ParsedAttributesView &DeclAttrs) {<br>
+ // DeclAttrs and Attrs cannot be both empty.<br>
+ assert((!Attrs.empty() || !DeclAttrs.empty()) &&<br>
+ "no type attributes in the expected location!");<br>
+<br>
+ ParsedAttr::Kind parsedKind = getAttrListKind(TL.getAttrKind());<br>
+ // Try to search for an attribute of matching kind in Attrs list.<br>
+ for (const ParsedAttr &AL : Attrs)<br>
+ if (AL.getKind() == parsedKind)<br>
+ return setAttributedTypeLoc(TL, AL);<br>
+<br>
+ for (const ParsedAttr &AL : DeclAttrs)<br>
+ if (AL.isCXX11Attribute() || AL.getKind() == parsedKind)<br>
+ return setAttributedTypeLoc(TL, AL);<br>
+ llvm_unreachable("no matching type attribute in expected location!");<br>
}<br>
<br>
namespace {<br>
class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {<br>
ASTContext &Context;<br>
- TypeProcessingState &State;<br>
const DeclSpec &DS;<br>
<br>
public:<br>
- TypeSpecLocFiller(ASTContext &Context, TypeProcessingState &State,<br>
- const DeclSpec &DS)<br>
- : Context(Context), State(State), DS(DS) {}<br>
+ TypeSpecLocFiller(ASTContext &Context, const DeclSpec &DS)<br>
+ : Context(Context), DS(DS) {}<br>
<br>
void VisitAttributedTypeLoc(AttributedTypeLoc TL) {<br>
+ fillAttributedTypeLoc(TL, DS.getAttributes(), ParsedAttributesView{});<br>
Visit(TL.getModifiedLoc());<br>
- fillAttributedTypeLoc(TL, State);<br>
}<br>
void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {<br>
Visit(TL.getUnqualifiedLoc());<br>
@@ -5408,13 +5442,11 @@ namespace {<br>
<br>
class DeclaratorLocFiller : public TypeLocVisitor<DeclaratorLocFiller> {<br>
ASTContext &Context;<br>
- TypeProcessingState &State;<br>
const DeclaratorChunk &Chunk;<br>
<br>
public:<br>
- DeclaratorLocFiller(ASTContext &Context, TypeProcessingState &State,<br>
- const DeclaratorChunk &Chunk)<br>
- : Context(Context), State(State), Chunk(Chunk) {}<br>
+ DeclaratorLocFiller(ASTContext &Context, const DeclaratorChunk &Chunk)<br>
+ : Context(Context), Chunk(Chunk) {}<br>
<br>
void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {<br>
llvm_unreachable("qualified type locs not expected here!");<br>
@@ -5424,7 +5456,7 @@ namespace {<br>
}<br>
<br>
void VisitAttributedTypeLoc(AttributedTypeLoc TL) {<br>
- fillAttributedTypeLoc(TL, State);<br>
+ fillAttributedTypeLoc(TL, Chunk.getAttrs(), ParsedAttributesView{});<br>
}<br>
void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {<br>
// nothing<br>
@@ -5581,13 +5613,10 @@ fillDependentAddressSpaceTypeLoc(Depende<br>
/// up in the normal place in the declaration specifiers (such as a C++<br>
/// conversion function), this pointer will refer to a type source information<br>
/// for that return type.<br>
-static TypeSourceInfo *<br>
-GetTypeSourceInfoForDeclarator(TypeProcessingState &State,<br>
- QualType T, TypeSourceInfo *ReturnTypeInfo) {<br>
- Sema &S = State.getSema();<br>
- Declarator &D = State.getDeclarator();<br>
-<br>
- TypeSourceInfo *TInfo = S.Context.CreateTypeSourceInfo(T);<br>
+TypeSourceInfo *<br>
+Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,<br>
+ TypeSourceInfo *ReturnTypeInfo) {<br>
+ TypeSourceInfo *TInfo = Context.CreateTypeSourceInfo(T);<br>
UnqualTypeLoc CurrTL = TInfo->getTypeLoc().getUnqualifiedLoc();<br>
<br>
// Handle parameter packs whose type is a pack expansion.<br>
@@ -5597,6 +5626,7 @@ GetTypeSourceInfoForDeclarator(TypeProce<br>
}<br>
<br>
for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {<br>
+<br>
if (DependentAddressSpaceTypeLoc DASTL =<br>
CurrTL.getAs<DependentAddressSpaceTypeLoc>()) {<br>
fillDependentAddressSpaceTypeLoc(DASTL, D.getTypeObject(i).getAttrs());<br>
@@ -5611,7 +5641,8 @@ GetTypeSourceInfoForDeclarator(TypeProce<br>
}<br>
<br>
while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) {<br>
- fillAttributedTypeLoc(TL, State);<br>
+ fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs(),<br>
+ D.getAttributes());<br>
CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();<br>
}<br>
<br>
@@ -5619,7 +5650,7 @@ GetTypeSourceInfoForDeclarator(TypeProce<br>
while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>())<br>
CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();<br>
<br>
- DeclaratorLocFiller(S.Context, State, D.getTypeObject(i)).Visit(CurrTL);<br>
+ DeclaratorLocFiller(Context, D.getTypeObject(i)).Visit(CurrTL);<br>
CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();<br>
}<br>
<br>
@@ -5630,7 +5661,7 @@ GetTypeSourceInfoForDeclarator(TypeProce<br>
assert(TL.getFullDataSize() == CurrTL.getFullDataSize());<br>
memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());<br>
} else {<br>
- TypeSpecLocFiller(S.Context, State, D.getDeclSpec()).Visit(CurrTL);<br>
+ TypeSpecLocFiller(Context, D.getDeclSpec()).Visit(CurrTL);<br>
}<br>
<br>
return TInfo;<br>
@@ -5859,7 +5890,7 @@ static bool hasDirectOwnershipQualifier(<br>
while (true) {<br>
// __strong id<br>
if (const AttributedType *attr = dyn_cast<AttributedType>(type)) {<br>
- if (attr->getAttrKind() == attr::ObjCOwnership)<br>
+ if (attr->getAttrKind() == AttributedType::attr_objc_ownership)<br>
return true;<br>
<br>
type = attr->getModifiedType();<br>
@@ -6003,9 +6034,9 @@ static bool handleObjCOwnershipTypeAttr(<br>
// the coexistence problems with __unsafe_unretained.<br>
if (!S.getLangOpts().ObjCAutoRefCount &&<br>
lifetime == Qualifiers::OCL_ExplicitNone) {<br>
- type = state.getAttributedType(<br>
- createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context, attr),<br>
- type, type);<br>
+ type = S.Context.getAttributedType(<br>
+ AttributedType::attr_objc_inert_unsafe_unretained,<br>
+ type, type);<br>
return true;<br>
}<br>
<br>
@@ -6015,12 +6046,9 @@ static bool handleObjCOwnershipTypeAttr(<br>
<br>
// If we have a valid source location for the attribute, use an<br>
// AttributedType instead.<br>
- if (AttrLoc.isValid()) {<br>
- type = state.getAttributedType(::new (S.Context) ObjCOwnershipAttr(<br>
- attr.getRange(), S.Context, II,<br>
- attr.getAttributeSpellingListIndex()),<br>
- origType, type);<br>
- }<br>
+ if (AttrLoc.isValid())<br>
+ type = S.Context.getAttributedType(AttributedType::attr_objc_ownership,<br>
+ origType, type);<br>
<br>
auto diagnoseOrDelay = [](Sema &S, SourceLocation loc,<br>
unsigned diagnostic, QualType type) {<br>
@@ -6120,10 +6148,8 @@ static bool handleObjCGCTypeAttr(TypePro<br>
<br>
// Make an attributed type to preserve the source information.<br>
if (attr.getLoc().isValid())<br>
- type = state.getAttributedType(<br>
- ::new (S.Context) ObjCGCAttr(attr.getRange(), S.Context, II,<br>
- attr.getAttributeSpellingListIndex()),<br>
- origType, type);<br>
+ type = S.Context.getAttributedType(AttributedType::attr_objc_gc,<br>
+ origType, type);<br>
<br>
return true;<br>
}<br>
@@ -6266,50 +6292,37 @@ namespace {<br>
} // end anonymous namespace<br>
<br>
static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,<br>
- ParsedAttr &PAttr, QualType &Type) {<br>
+ ParsedAttr &Attr, QualType &Type) {<br>
Sema &S = State.getSema();<br>
<br>
- Attr *A;<br>
- switch (PAttr.getKind()) {<br>
- default: llvm_unreachable("Unknown attribute kind");<br>
- case ParsedAttr::AT_Ptr32:<br>
- A = createSimpleAttr<Ptr32Attr>(S.Context, PAttr);<br>
- break;<br>
- case ParsedAttr::AT_Ptr64:<br>
- A = createSimpleAttr<Ptr64Attr>(S.Context, PAttr);<br>
- break;<br>
- case ParsedAttr::AT_SPtr:<br>
- A = createSimpleAttr<SPtrAttr>(S.Context, PAttr);<br>
- break;<br>
- case ParsedAttr::AT_UPtr:<br>
- A = createSimpleAttr<UPtrAttr>(S.Context, PAttr);<br>
- break;<br>
- }<br>
-<br>
- attr::Kind NewAttrKind = A->getKind();<br>
+ ParsedAttr::Kind Kind = Attr.getKind();<br>
QualType Desugared = Type;<br>
const AttributedType *AT = dyn_cast<AttributedType>(Type);<br>
while (AT) {<br>
- attr::Kind CurAttrKind = AT->getAttrKind();<br>
+ AttributedType::Kind CurAttrKind = AT->getAttrKind();<br>
<br>
// You cannot specify duplicate type attributes, so if the attribute has<br>
// already been applied, flag it.<br>
- if (NewAttrKind == CurAttrKind) {<br>
- S.Diag(PAttr.getLoc(), diag::warn_duplicate_attribute_exact)<br>
- << PAttr.getName();<br>
+ if (getAttrListKind(CurAttrKind) == Kind) {<br>
+ S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute_exact)<br>
+ << Attr.getName();<br>
return true;<br>
}<br>
<br>
// You cannot have both __sptr and __uptr on the same type, nor can you<br>
// have __ptr32 and __ptr64.<br>
- </blockquote></div>