From: Enea Zaffanella Date: Thu, 20 Jun 2013 12:46:19 +0000 (+0000) Subject: Improved source code fidelity for gcc mode attribute. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c2fa6b6f9a89f55397355937544fbbe8258ead5d;p=clang Improved source code fidelity for gcc mode attribute. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184417 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index a2d7b868a3..5d94278e99 100644 --- a/include/clang/AST/Decl.h +++ b/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 { virtual void anchor(); - /// UnderlyingType - This is the type the typedef is set to. - TypeSourceInfo *TInfo; + typedef std::pair ModedTInfo; + llvm::PointerUnion 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 redeclarable_base; virtual TypedefNameDecl *getNextRedeclaration() { @@ -2339,8 +2339,23 @@ public: using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + bool isModed() const { return MaybeModedTInfo.is(); } + TypeSourceInfo *getTypeSourceInfo() const { - return TInfo; + return isModed() + ? MaybeModedTInfo.get()->first + : MaybeModedTInfo.get(); + } + QualType getUnderlyingType() const { + return isModed() + ? MaybeModedTInfo.get()->second + : MaybeModedTInfo.get()->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/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index a42b272c72..cdb567dea0 100644 --- a/include/clang/Basic/Attr.td +++ b/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/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 1c9fd2d5f6..e738ff2b87 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/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(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/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 684148879b..9a68ca5a75 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/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(D)) { - // FIXME: preserve existing source info. - TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); - } else + if (TypedefNameDecl *TD = dyn_cast(D)) + TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy); + else cast(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/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index d2fed4637c..ffbff3882b 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/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/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index bcbf0e3d1b..b60106408f 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/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/test/SemaCXX/attr-print.cpp b/test/SemaCXX/attr-print.cpp index 2e7478904f..a07eeff564 100644 --- a/test/SemaCXX/attr-print.cpp +++ b/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/test/SemaCXX/cxx11-attr-print.cpp b/test/SemaCXX/cxx11-attr-print.cpp index 19de5b5a64..c82e5d2484 100644 --- a/test/SemaCXX/cxx11-attr-print.cpp +++ b/test/SemaCXX/cxx11-attr-print.cpp @@ -75,3 +75,6 @@ template struct S { // CHECK: static int f() __attribute__((pure)) // CHECK: static int g() {{\[}}[gnu::pure]] template struct S; + +// CHECK: using Small2 {{\[}}[gnu::mode(byte)]] = int; +using Small2 [[gnu::mode(byte)]] = int; diff --git a/test/SemaObjC/attr-print.m b/test/SemaObjC/attr-print.m new file mode 100644 index 0000000000..e3405d239e --- /dev/null +++ b/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;