diff options
| -rw-r--r-- | clang/include/clang/AST/Decl.h | 30 | ||||
| -rw-r--r-- | clang/include/clang/Basic/Attr.td | 1 | ||||
| -rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 11 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 5 | ||||
| -rw-r--r-- | clang/test/SemaCXX/attr-print.cpp | 6 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx11-attr-print.cpp | 3 | ||||
| -rw-r--r-- | clang/test/SemaObjC/attr-print.m | 9 |
9 files changed, 61 insertions, 24 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index a2d7b868a3a..5d94278e99d 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -2312,14 +2312,14 @@ public: /// Base class for declarations which introduce a typedef-name. class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> { virtual void anchor(); - /// UnderlyingType - This is the type the typedef is set to. - TypeSourceInfo *TInfo; + typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo; + llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo; protected: TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) - : TypeDecl(DK, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {} + : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {} typedef Redeclarable<TypedefNameDecl> redeclarable_base; virtual TypedefNameDecl *getNextRedeclaration() { @@ -2339,8 +2339,23 @@ public: using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + bool isModed() const { return MaybeModedTInfo.is<ModedTInfo*>(); } + TypeSourceInfo *getTypeSourceInfo() const { - return TInfo; + return isModed() + ? MaybeModedTInfo.get<ModedTInfo*>()->first + : MaybeModedTInfo.get<TypeSourceInfo*>(); + } + QualType getUnderlyingType() const { + return isModed() + ? MaybeModedTInfo.get<ModedTInfo*>()->second + : MaybeModedTInfo.get<TypeSourceInfo*>()->getType(); + } + void setTypeSourceInfo(TypeSourceInfo *newType) { + MaybeModedTInfo = newType; + } + void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) { + MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy); } /// Retrieves the canonical declaration of this typedef-name. @@ -2351,13 +2366,6 @@ public: return getFirstDeclaration(); } - QualType getUnderlyingType() const { - return TInfo->getType(); - } - void setTypeSourceInfo(TypeSourceInfo *newType) { - TInfo = newType; - } - // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index a42b272c72c..cdb567dea0d 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -441,7 +441,6 @@ def Mips16 : InheritableAttr { def Mode : Attr { let Spellings = [GNU<"mode">, CXX11<"gnu", "mode">]; let Args = [IdentifierArgument<"Mode">]; - let ASTNode = 0; } def Naked : InheritableAttr { diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 1c9fd2d5f61..e738ff2b87a 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -337,12 +337,14 @@ void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) { if (D->isModulePrivate()) Out << "__module_private__ "; } - D->getUnderlyingType().print(Out, Policy, D->getName()); + D->getTypeSourceInfo()->getType().print(Out, Policy, D->getName()); prettyPrintAttributes(D); } void DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) { - Out << "using " << *D << " = " << D->getUnderlyingType().getAsString(Policy); + Out << "using " << *D; + prettyPrintAttributes(D); + Out << " = " << D->getTypeSourceInfo()->getType().getAsString(Policy); } void DeclPrinter::VisitEnumDecl(EnumDecl *D) { @@ -665,9 +667,9 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { Out << "__module_private__ "; } - QualType T = D->getASTContext().getUnqualifiedObjCPointerType(D->getType()); - if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) - T = Parm->getOriginalType(); + QualType T = D->getTypeSourceInfo() + ? D->getTypeSourceInfo()->getType() + : D->getASTContext().getUnqualifiedObjCPointerType(D->getType()); T.print(Out, Policy, D->getName()); Expr *Init = D->getInit(); if (!Policy.SuppressInitializers && Init) { diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 684148879b2..9a68ca5a752 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3740,11 +3740,14 @@ static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { } // Install the new type. - if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { - // FIXME: preserve existing source info. - TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); - } else + if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) + TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy); + else cast<ValueDecl>(D)->setType(NewTy); + + D->addAttr(::new (S.Context) + ModeAttr(Attr.getRange(), S.Context, Name, + Attr.getAttributeSpellingListIndex())); } static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index d2fed4637c8..ffbff3882b2 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -417,8 +417,12 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) { void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) { RedeclarableResult Redecl = VisitRedeclarable(TD); VisitTypeDecl(TD); - - TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx)); + TypeSourceInfo *TInfo = GetTypeSourceInfo(Record, Idx); + if (Record[Idx++]) { // isModed + QualType modedT = Reader.readType(F, Record, Idx); + TD->setModedTypeSourceInfo(TInfo, modedT); + } else + TD->setTypeSourceInfo(TInfo); mergeRedeclarable(TD, Redecl); } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index bcbf0e3d1bd..b60106408f1 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -184,7 +184,10 @@ void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) { void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) { VisitRedeclarable(D); VisitTypeDecl(D); - Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record); + Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record); + Record.push_back(D->isModed()); + if (D->isModed()) + Writer.AddTypeRef(D->getUnderlyingType(), Record); } void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) { diff --git a/clang/test/SemaCXX/attr-print.cpp b/clang/test/SemaCXX/attr-print.cpp index 2e7478904f1..a07eeff5646 100644 --- a/clang/test/SemaCXX/attr-print.cpp +++ b/clang/test/SemaCXX/attr-print.cpp @@ -16,3 +16,9 @@ void bar() __attribute__((__const)); // FIXME: Print this with correct format and order. // CHECK: void foo1() __attribute__((pure)) __attribute__((noinline)); void foo1() __attribute__((noinline, pure)); + +// CHECK: typedef int Small1 __attribute__((mode(byte))); +typedef int Small1 __attribute__((mode(byte))); + +// CHECK: int small __attribute__((mode(byte))); +int small __attribute__((mode(byte))); diff --git a/clang/test/SemaCXX/cxx11-attr-print.cpp b/clang/test/SemaCXX/cxx11-attr-print.cpp index 19de5b5a640..c82e5d24844 100644 --- a/clang/test/SemaCXX/cxx11-attr-print.cpp +++ b/clang/test/SemaCXX/cxx11-attr-print.cpp @@ -75,3 +75,6 @@ template <typename T> struct S { // CHECK: static int f() __attribute__((pure)) // CHECK: static int g() {{\[}}[gnu::pure]] template struct S<int>; + +// CHECK: using Small2 {{\[}}[gnu::mode(byte)]] = int; +using Small2 [[gnu::mode(byte)]] = int; diff --git a/clang/test/SemaObjC/attr-print.m b/clang/test/SemaObjC/attr-print.m new file mode 100644 index 00000000000..e3405d239e3 --- /dev/null +++ b/clang/test/SemaObjC/attr-print.m @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -fobjc-arc -ast-print | FileCheck %s + +__strong id x; +id y; +__strong id z; + +// CHECK: __strong id x; +// CHECK-NOT: __strong id y; +// CHECK: __strong id z; |

