r199378 - Distinguish between attributes explicitly written at the request of the user, and attributes implicitly generated to assist in bookkeeping by the compiler. This is done so by table generating a CreateImplicit method for each attribute.

Aaron Ballman aaron at aaronballman.com
Thu Jan 16 05:03:15 PST 2014


Author: aaronballman
Date: Thu Jan 16 07:03:14 2014
New Revision: 199378

URL: http://llvm.org/viewvc/llvm-project?rev=199378&view=rev
Log:
Distinguish between attributes explicitly written at the request of the user, and attributes implicitly generated to assist in bookkeeping by the compiler. This is done so by table generating a CreateImplicit method for each attribute.

Additionally, remove the optional nature of the spelling list index when creating attributes. This is supported by table generating a Spelling enumeration when the spellings for an attribute are distinct enough to warrant it.

Modified:
    cfe/trunk/include/clang/AST/Attr.h
    cfe/trunk/lib/AST/ASTDumper.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaAttr.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp
    cfe/trunk/lib/Sema/SemaStmtAttr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/Misc/ast-dump-attr.cpp
    cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Thu Jan 16 07:03:14 2014
@@ -48,10 +48,9 @@ protected:
   /// An index into the spelling list of an
   /// attribute defined in Attr.td file.
   unsigned SpellingListIndex : 4;
-
   bool Inherited : 1;
-
   bool IsPackExpansion : 1;
+  bool Implicit : 1;
 
   virtual ~Attr();
 
@@ -76,7 +75,7 @@ public:
 protected:
   Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
     : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
-      Inherited(false), IsPackExpansion(false) {}
+      Inherited(false), IsPackExpansion(false), Implicit(false) {}
 
 public:
 
@@ -93,6 +92,11 @@ public:
 
   bool isInherited() const { return Inherited; }
 
+  /// \brief Returns true if the attribute has been implicitly created instead
+  /// of explicitly written by the user.
+  bool isImplicit() const { return Implicit; }
+  void setImplicit(bool I) { Implicit = I; }
+
   void setPackExpansion(bool PE) { IsPackExpansion = PE; }
   bool isPackExpansion() const { return IsPackExpansion; }
 

Modified: cfe/trunk/lib/AST/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)
+++ cfe/trunk/lib/AST/ASTDumper.cpp Thu Jan 16 07:03:14 2014
@@ -569,6 +569,7 @@ void ASTDumper::dumpAttr(const Attr *A)
   IndentScope Indent(*this);
   {
     ColorScope Color(*this, AttrColor);
+
     switch (A->getKind()) {
 #define ATTR(X) case attr::X: OS << #X; break;
 #include "clang/Basic/AttrList.inc"
@@ -579,6 +580,8 @@ void ASTDumper::dumpAttr(const Attr *A)
   dumpPointer(A);
   dumpSourceRange(A->getRange());
 #include "clang/AST/AttrDump.inc"
+  if (A->isImplicit())
+    OS << " Implicit";
 }
 
 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Thu Jan 16 07:03:14 2014
@@ -941,7 +941,7 @@ void ObjCMethodDecl::createImplicitParam
   setSelfDecl(self);
 
   if (selfIsConsumed)
-    self->addAttr(new (Context) NSConsumedAttr(SourceLocation(), Context));
+    self->addAttr(NSConsumedAttr::CreateImplicit(Context));
 
   if (selfIsPseudoStrong)
     self->setARCPseudoStrong(true);

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Jan 16 07:03:14 2014
@@ -255,7 +255,7 @@ bool Sema::makeUnavailableInSystemHeader
   // If the function is already unavailable, it's not an error.
   if (fn->hasAttr<UnavailableAttr>()) return true;
 
-  fn->addAttr(new (Context) UnavailableAttr(loc, Context, msg));
+  fn->addAttr(UnavailableAttr::CreateImplicit(Context, msg, loc));
   return true;
 }
 

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Thu Jan 16 07:03:14 2014
@@ -122,10 +122,9 @@ void Sema::AddAlignmentAttributesForReco
   // Otherwise, check to see if we need a max field alignment attribute.
   if (unsigned Alignment = Stack->getAlignment()) {
     if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
-      RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context));
+      RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
     else
-      RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(),
-                                                        Context,
+      RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context,
                                                         Alignment * 8));
   }
 }
@@ -133,7 +132,7 @@ void Sema::AddAlignmentAttributesForReco
 void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
   if (!MSStructPragmaOn)
     return;
-  RD->addAttr(::new (Context) MsStructAttr(SourceLocation(), Context));
+  RD->addAttr(MsStructAttr::CreateImplicit(Context));
 }
 
 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
@@ -312,7 +311,7 @@ void Sema::ActOnPragmaUnused(const Token
   if (VD->isUsed())
     Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
 
-  VD->addAttr(::new (Context) UnusedAttr(IdTok.getLocation(), Context));
+  VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation()));
 }
 
 void Sema::AddCFAuditedAttribute(Decl *D) {
@@ -324,7 +323,7 @@ void Sema::AddCFAuditedAttribute(Decl *D
       D->hasAttr<CFUnknownTransferAttr>())
     return;
 
-  D->addAttr(::new (Context) CFAuditedTransferAttr(Loc, Context));
+  D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
 }
 
 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
@@ -346,7 +345,7 @@ void Sema::AddPushedVisibilityAttribute(
     = (VisibilityAttr::VisibilityType) rawType;
   SourceLocation loc = Stack->back().second;
 
-  D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
+  D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
 }
 
 /// FreeVisContext - Deallocate and null out VisContext.

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 16 07:03:14 2014
@@ -5420,7 +5420,7 @@ Sema::ActOnVariableDeclarator(Scope *S,
     }
 
     NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
-                                                Context, Label));
+                                                Context, Label, 0));
   } else if (!ExtnameUndeclaredIdentifiers.empty()) {
     llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
       ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
@@ -6929,7 +6929,7 @@ Sema::ActOnFunctionDeclarator(Scope *S,
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
     NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
-                                                SE->getString()));
+                                                SE->getString(), 0));
   } else if (!ExtnameUndeclaredIdentifiers.empty()) {
     llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
       ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier());
@@ -7005,7 +7005,7 @@ Sema::ActOnFunctionDeclarator(Scope *S,
   if (D.getDeclSpec().isNoreturnSpecified())
     NewFD->addAttr(
         ::new(Context) C11NoReturnAttr(D.getDeclSpec().getNoreturnSpecLoc(),
-                                       Context));
+                                       Context, 0));
 
   // Functions returning a variably modified type violate C99 6.7.5.2p2
   // because all functions have linkage.
@@ -7027,8 +7027,7 @@ Sema::ActOnFunctionDeclarator(Scope *S,
     // Attach the attribute to the new decl. Don't apply the attribute if it
     // returns an instance of the class (e.g. assignment operators).
     if (!MD || MD->getParent() != Ret) {
-      NewFD->addAttr(new (Context) WarnUnusedResultAttr(SourceRange(),
-                                                        Context));
+      NewFD->addAttr(WarnUnusedResultAttr::CreateImplicit(Context));
     }
   }
 
@@ -7485,8 +7484,7 @@ bool Sema::CheckFunctionDeclaration(Scop
         if (OverloadedDecl)
           Diag(OverloadedDecl->getLocation(),
                diag::note_attribute_overloadable_prev_overload);
-        NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(),
-                                                        Context));
+        NewFD->addAttr(OverloadableAttr::CreateImplicit(Context));
       }
     }
   }
@@ -7509,8 +7507,7 @@ bool Sema::CheckFunctionDeclaration(Scop
             << Redeclaration << NewFD;
           Diag(Previous.getFoundDecl()->getLocation(),
                diag::note_attribute_overloadable_prev_overload);
-          NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(),
-                                                          Context));
+          NewFD->addAttr(OverloadableAttr::CreateImplicit(Context));
         }
         if (IsOverload(NewFD, cast<FunctionDecl>(OldDecl), false)) {
           Redeclaration = false;
@@ -10090,19 +10087,21 @@ void Sema::AddKnownFunctionAttributes(Fu
         if (FormatIdx < NumParams && // NumParams may be 0 (e.g. vfprintf)
             FD->getParamDecl(FormatIdx)->getType()->isObjCObjectPointerType())
           fmt = "NSString";
-        FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+        FD->addAttr(FormatAttr::CreateImplicit(Context,
                                                &Context.Idents.get(fmt),
                                                FormatIdx+1,
-                                               HasVAListArg ? 0 : FormatIdx+2));
+                                               HasVAListArg ? 0 : FormatIdx+2,
+                                               FD->getLocation()));
       }
     }
     if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
                                              HasVAListArg)) {
      if (!FD->hasAttr<FormatAttr>())
-       FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+       FD->addAttr(FormatAttr::CreateImplicit(Context,
                                               &Context.Idents.get("scanf"),
                                               FormatIdx+1,
-                                              HasVAListArg ? 0 : FormatIdx+2));
+                                              HasVAListArg ? 0 : FormatIdx+2,
+                                              FD->getLocation()));
     }
 
     // Mark const if we don't care about errno and that is the only
@@ -10111,16 +10110,17 @@ void Sema::AddKnownFunctionAttributes(Fu
     if (!getLangOpts().MathErrno &&
         Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
       if (!FD->hasAttr<ConstAttr>())
-        FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
+        FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation()));
     }
 
     if (Context.BuiltinInfo.isReturnsTwice(BuiltinID) &&
         !FD->hasAttr<ReturnsTwiceAttr>())
-      FD->addAttr(::new (Context) ReturnsTwiceAttr(FD->getLocation(), Context));
+      FD->addAttr(ReturnsTwiceAttr::CreateImplicit(Context,
+                                         FD->getLocation()));
     if (Context.BuiltinInfo.isNoThrow(BuiltinID) && !FD->hasAttr<NoThrowAttr>())
-      FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
+      FD->addAttr(NoThrowAttr::CreateImplicit(Context, FD->getLocation()));
     if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->hasAttr<ConstAttr>())
-      FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
+      FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation()));
   }
 
   IdentifierInfo *Name = FD->getIdentifier();
@@ -10140,16 +10140,18 @@ void Sema::AddKnownFunctionAttributes(Fu
     // FIXME: asprintf and vasprintf aren't C99 functions. Should they be
     // target-specific builtins, perhaps?
     if (!FD->hasAttr<FormatAttr>())
-      FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+      FD->addAttr(FormatAttr::CreateImplicit(Context,
                                              &Context.Idents.get("printf"), 2,
-                                             Name->isStr("vasprintf") ? 0 : 3));
+                                             Name->isStr("vasprintf") ? 0 : 3,
+                                             FD->getLocation()));
   }
 
   if (Name->isStr("__CFStringMakeConstantString")) {
     // We already have a __builtin___CFStringMakeConstantString,
     // but builds that use -fno-constant-cfstrings don't go through that.
     if (!FD->hasAttr<FormatArgAttr>())
-      FD->addAttr(::new (Context) FormatArgAttr(FD->getLocation(), Context, 1));
+      FD->addAttr(FormatArgAttr::CreateImplicit(Context, 1,
+                                                FD->getLocation()));
   }
 }
 
@@ -11697,8 +11699,9 @@ bool Sema::CheckNontrivialField(FieldDec
           SourceLocation Loc = FD->getLocation();
           if (getSourceManager().isInSystemHeader(Loc)) {
             if (!FD->hasAttr<UnavailableAttr>())
-              FD->addAttr(new (Context) UnavailableAttr(Loc, Context,
-                                  "this system field has retaining ownership"));
+              FD->addAttr(UnavailableAttr::CreateImplicit(Context,
+                                  "this system field has retaining ownership",
+                                  Loc));
             return false;
           }
         }
@@ -12071,8 +12074,9 @@ void Sema::ActOnFields(Scope *S, SourceL
         SourceLocation loc = FD->getLocation();
         if (getSourceManager().isInSystemHeader(loc)) {
           if (!FD->hasAttr<UnavailableAttr>()) {
-            FD->addAttr(new (Context) UnavailableAttr(loc, Context,
-                              "this system field has retaining ownership"));
+            FD->addAttr(UnavailableAttr::CreateImplicit(Context,
+                              "this system field has retaining ownership",
+                              loc));
           }
         } else {
           Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag) 
@@ -13046,8 +13050,8 @@ void Sema::ActOnPragmaRedefineExtname(Id
                                       SourceLocation AliasNameLoc) {
   Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc,
                                     LookupOrdinaryName);
-  AsmLabelAttr *Attr =
-     ::new (Context) AsmLabelAttr(AliasNameLoc, Context, AliasName->getName());
+  AsmLabelAttr *Attr = ::new (Context) AsmLabelAttr(AliasNameLoc, Context,
+                                                    AliasName->getName(), 0);
 
   if (PrevDecl) 
     PrevDecl->addAttr(Attr);
@@ -13062,7 +13066,7 @@ void Sema::ActOnPragmaWeakID(IdentifierI
   Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
 
   if (PrevDecl) {
-    PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context));
+    PrevDecl->addAttr(WeakAttr::CreateImplicit(Context, PragmaLoc));
   } else {
     (void)WeakUndeclaredIdentifiers.insert(
       std::pair<IdentifierInfo*,WeakInfo>

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Jan 16 07:03:14 2014
@@ -565,7 +565,8 @@ static void handleGuardedByAttr(Sema &S,
   if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
     return;
 
-  D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
+  D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handlePtGuardedByAttr(Sema &S, Decl *D,
@@ -578,7 +579,8 @@ static void handlePtGuardedByAttr(Sema &
     return;
 
   D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
-                                               S.Context, Arg));
+                                               S.Context, Arg,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
@@ -1083,7 +1085,8 @@ static void handleExtVectorTypeAttr(Sema
 
 static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (TagDecl *TD = dyn_cast<TagDecl>(D))
-    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
+    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context,
+                                        Attr.getAttributeSpellingListIndex()));
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
     // If the alignment is less than or equal to 8 bits, the packed attribute
     // has no effect.
@@ -2054,7 +2057,8 @@ static void handleObjCMethodFamilyAttr(S
   }
 
   method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
-                                                       S.Context, F));
+                                                       S.Context, F,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2297,7 +2301,8 @@ static void handleVecTypeHint(Sema &S, D
   }
 
   D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
-                                               ParmTSI));
+                                               ParmTSI,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
@@ -3787,8 +3792,10 @@ static void handleMSP430InterruptAttr(Se
     return;
   }
 
-  D->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
-  D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
+  D->addAttr(::new (S.Context)
+              MSP430InterruptAttr(Attr.getLoc(), S.Context, Num,
+                                  Attr.getAttributeSpellingListIndex()));
+  D->addAttr(UsedAttr::CreateImplicit(S.Context));
 }
 
 static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3819,8 +3826,9 @@ static void handleX86ForceAlignArgPointe
     return;
   }
 
-  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getRange(),
-    S.Context));
+  D->addAttr(::new (S.Context)
+              X86ForceAlignArgPointerAttr(Attr.getRange(), S.Context,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
@@ -4423,9 +4431,9 @@ void Sema::DeclApplyPragmaWeak(Scope *S,
   if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
     IdentifierInfo *NDId = ND->getIdentifier();
     NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
-    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
-                                            NDId->getName()));
-    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
+    NewD->addAttr(AliasAttr::CreateImplicit(Context, NDId->getName(),
+                                            W.getLocation()));
+    NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
     WeakTopLevelDecl.push_back(NewD);
     // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
     // to insert Decl at TU scope, sorry.
@@ -4434,7 +4442,7 @@ void Sema::DeclApplyPragmaWeak(Scope *S,
     PushOnScopeChains(NewD, S);
     CurContext = SavedContext;
   } else { // just add weak to existing
-    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
+    ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
   }
 }
 
@@ -4503,8 +4511,9 @@ static bool isForbiddenTypeAllowed(Sema
 static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
                                        Decl *decl) {
   if (decl && isForbiddenTypeAllowed(S, decl)) {
-    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
-                        "this system declaration uses an unsupported type"));
+    decl->addAttr(UnavailableAttr::CreateImplicit(S.Context,
+                        "this system declaration uses an unsupported type",
+                        diag.Loc));
     return;
   }
   if (S.getLangOpts().ObjCAutoRefCount)

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jan 16 07:03:14 2014
@@ -1520,7 +1520,7 @@ bool Sema::AttachBaseSpecifiers(CXXRecor
           Invalid = true;
         }
         if (RD->hasAttr<WeakAttr>())
-          Class->addAttr(::new (Context) WeakAttr(SourceRange(), Context));
+          Class->addAttr(WeakAttr::CreateImplicit(Context));
       }
     }
   }
@@ -2094,7 +2094,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S,
   }
 
   if (VS.isOverrideSpecified())
-    Member->addAttr(new (Context) OverrideAttr(VS.getOverrideLoc(), Context));
+    Member->addAttr(new (Context) OverrideAttr(VS.getOverrideLoc(), Context, 0));
   if (VS.isFinalSpecified())
     Member->addAttr(new (Context) FinalAttr(VS.getFinalLoc(), Context,
                                             VS.isFinalSpelledSealed()));

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Jan 16 07:03:14 2014
@@ -98,8 +98,9 @@ bool Sema::checkInitMethod(ObjCMethodDec
   // If we're in a system header, and this is not a call, just make
   // the method unusable.
   if (receiverTypeIfCall.isNull() && getSourceManager().isInSystemHeader(loc)) {
-    method->addAttr(new (Context) UnavailableAttr(loc, Context,
-                "init method returns a type unrelated to its receiver type"));
+    method->addAttr(UnavailableAttr::CreateImplicit(Context,
+                "init method returns a type unrelated to its receiver type",
+                loc));
     return true;
   }
 
@@ -230,8 +231,7 @@ bool Sema::CheckARCMethodDecl(ObjCMethod
     if (checkInitMethod(method, QualType()))
       return true;
 
-    method->addAttr(new (Context) NSConsumesSelfAttr(SourceLocation(),
-                                                     Context));
+    method->addAttr(NSConsumesSelfAttr::CreateImplicit(Context));
 
     // Don't add a second copy of this attribute, but otherwise don't
     // let it be suppressed.
@@ -250,8 +250,7 @@ bool Sema::CheckARCMethodDecl(ObjCMethod
     break;
   }
 
-  method->addAttr(new (Context) NSReturnsRetainedAttr(SourceLocation(),
-                                                      Context));
+  method->addAttr(NSReturnsRetainedAttr::CreateImplicit(Context));
   return false;
 }
 
@@ -3167,8 +3166,8 @@ Decl *Sema::ActOnMethodDeclaration(
     if (IMD && IMD->hasAttr<ObjCRequiresSuperAttr>() &&
         !ObjCMethod->hasAttr<ObjCRequiresSuperAttr>()) {
       // merge the attribute into implementation.
-      ObjCMethod->addAttr(
-        new (Context) ObjCRequiresSuperAttr(ObjCMethod->getLocation(), Context));
+      ObjCMethod->addAttr(ObjCRequiresSuperAttr::CreateImplicit(Context,
+                                                   ObjCMethod->getLocation()));
     }
     if (isa<ObjCCategoryImplDecl>(ImpDecl)) {
       ObjCMethodFamily family = ObjCMethod->getMethodFamily();

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jan 16 07:03:14 2014
@@ -2058,8 +2058,7 @@ void Sema::DeclareGlobalAllocationFuncti
         if (InitialParam1Type == Param1 &&
             (NumParams == 1 || InitialParam2Type == Param2)) {
           if (AddMallocAttr && !Func->hasAttr<MallocAttr>())
-            Func->addAttr(::new (Context) MallocAttr(SourceLocation(),
-                                                     Context));
+            Func->addAttr(MallocAttr::CreateImplicit(Context));
           // Make the function visible to name lookup, even if we found it in
           // an unimported module. It either is an implicitly-declared global
           // allocation function, or is suppressing that function.
@@ -2102,7 +2101,7 @@ void Sema::DeclareGlobalAllocationFuncti
   Alloc->setImplicit();
 
   if (AddMallocAttr)
-    Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
+    Alloc->addAttr(MallocAttr::CreateImplicit(Context));
 
   ParmVarDecl *ParamDecls[2];
   for (unsigned I = 0; I != NumParams; ++I)

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Thu Jan 16 07:03:14 2014
@@ -1930,16 +1930,16 @@ void Sema::ProcessPropertyDecl(ObjCPrope
     if (lexicalDC)
       GetterMethod->setLexicalDeclContext(lexicalDC);
     if (property->hasAttr<NSReturnsNotRetainedAttr>())
-      GetterMethod->addAttr(
-        ::new (Context) NSReturnsNotRetainedAttr(Loc, Context));
+      GetterMethod->addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context,
+                                                                     Loc));
     
     if (property->hasAttr<ObjCReturnsInnerPointerAttr>())
       GetterMethod->addAttr(
-        ::new (Context) ObjCReturnsInnerPointerAttr(Loc, Context));
+        ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc));
     
     if (const SectionAttr *SA = property->getAttr<SectionAttr>())
-      GetterMethod->addAttr(::new (Context) SectionAttr(Loc,
-                                                        Context, SA->getName()));
+      GetterMethod->addAttr(SectionAttr::CreateImplicit(Context, SA->getName(),
+                                                        Loc));
 
     if (getLangOpts().ObjCAutoRefCount)
       CheckARCMethodDecl(GetterMethod);
@@ -1991,8 +1991,8 @@ void Sema::ProcessPropertyDecl(ObjCPrope
       if (lexicalDC)
         SetterMethod->setLexicalDeclContext(lexicalDC);
       if (const SectionAttr *SA = property->getAttr<SectionAttr>())
-        SetterMethod->addAttr(::new (Context) SectionAttr(Loc,
-                                                          Context, SA->getName()));
+        SetterMethod->addAttr(SectionAttr::CreateImplicit(Context,
+                                                          SA->getName(), Loc));
       // It's possible for the user to have set a very odd custom
       // setter selector that causes it to have a method family.
       if (getLangOpts().ObjCAutoRefCount)

Modified: cfe/trunk/lib/Sema/SemaStmtAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp Thu Jan 16 07:03:14 2014
@@ -40,7 +40,8 @@ static Attr *handleFallThroughAttr(Sema
     S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_outside_switch);
     return 0;
   }
-  return ::new (S.Context) FallThroughAttr(A.getRange(), S.Context);
+  return ::new (S.Context) FallThroughAttr(A.getRange(), S.Context,
+                                           A.getAttributeSpellingListIndex());
 }
 
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Jan 16 07:03:14 2014
@@ -157,8 +157,10 @@ static void instantiateDependentEnableIf
     return;
   }
 
-  EnableIfAttr *EIA = new (S.getASTContext()) EnableIfAttr(
-      A->getLocation(), S.getASTContext(), Cond, A->getMessage());
+  EnableIfAttr *EIA = new (S.getASTContext())
+                        EnableIfAttr(A->getLocation(), S.getASTContext(), Cond,
+                                     A->getMessage(),
+                                     A->getSpellingListIndex());
   New->addAttr(EIA);
 }
 
@@ -4391,7 +4393,7 @@ NamedDecl *Sema::FindInstantiatedDecl(So
   // find an instantiated decl for (T y) when the ParentDC for y is
   // the translation unit.  
   //   e.g. template <class T> void Foo(auto (*p)(T y) -> decltype(y())) {} 
-  //   float baz(float(*)()) { return 0.0; }
+  //   float baz(float(*)()) { return 0.0; }
   //   Foo(baz);
   // The better fix here is perhaps to ensure that a ParmVarDecl, by the time
   // it gets here, always has a FunctionOrMethod as its ParentDC??

Modified: cfe/trunk/test/Misc/ast-dump-attr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-attr.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/test/Misc/ast-dump-attr.cpp (original)
+++ cfe/trunk/test/Misc/ast-dump-attr.cpp Thu Jan 16 07:03:14 2014
@@ -103,3 +103,10 @@ N: __attribute(()) ;
 // CHECK: LabelStmt {{.*}} 'N'
 // CHECK-NEXT: NullStmt
 }
+
+namespace Test {
+extern "C" int printf(const char *format, ...);
+// CHECK: FunctionDecl{{.*}}printf
+// CHECK-NEXT: ParmVarDecl{{.*}}format{{.*}}'const char *'
+// CHECK-NEXT: FormatAttr{{.*}}printf 1 2 Implicit
+}
\ No newline at end of file

Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=199378&r1=199377&r2=199378&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Thu Jan 16 07:03:14 2014
@@ -14,6 +14,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
 #include "llvm/TableGen/StringMatcher.h"
@@ -61,6 +62,17 @@ static StringRef NormalizeAttrName(Strin
   return AttrName;
 }
 
+// Normalize the name by removing any and all leading and trailing underscores.
+// This is different from NormalizeAttrName in that it also handles names like
+// _pascal and __pascal.
+static StringRef NormalizeNameForSpellingComparison(StringRef Name) {
+  while (Name.startswith("_"))
+    Name = Name.substr(1, Name.size());
+  while (Name.endswith("_"))
+    Name = Name.substr(0, Name.size() - 1);
+  return Name;
+}
+
 // Normalize attribute spelling only if the spelling has both leading
 // and trailing underscores. For example, __ms_struct__ will be 
 // normalized to "ms_struct"; __cdecl will remain intact.
@@ -151,6 +163,10 @@ namespace {
 
     virtual bool isEnumArg() const { return false; }
     virtual bool isVariadicEnumArg() const { return false; }
+
+    virtual void writeImplicitCtorArgs(raw_ostream &OS) const {
+      OS << getUpperName();
+    }
   };
 
   class SimpleArgument : public Argument {
@@ -394,6 +410,9 @@ namespace {
     void writeCtorParameters(raw_ostream &OS) const {
       OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
     }
+    void writeImplicitCtorArgs(raw_ostream &OS) const {
+      OS << "Is" << getUpperName() << "Expr, " << getUpperName();
+    }
     void writeDeclarations(raw_ostream &OS) const {
       OS << "bool is" << getLowerName() << "Expr;\n";
       OS << "union {\n";
@@ -491,6 +510,9 @@ namespace {
       OS << getType() << " *" << getUpperName() << ", unsigned "
          << getUpperName() << "Size";
     }
+    void writeImplicitCtorArgs(raw_ostream &OS) const {
+      OS << getUpperName() << ", " << getUpperName() << "Size";
+    }
     void writeDeclarations(raw_ostream &OS) const {
       OS << "  unsigned " << getLowerName() << "Size;\n";
       OS << "  " << getType() << " *" << getLowerName() << ";";
@@ -1104,6 +1126,20 @@ static void writeAttrAccessorDefinition(
   }
 }
 
+static bool SpellingNamesAreCommon(const std::vector<Record *>& Spellings) {
+  assert(!Spellings.empty() && "An empty list of spellings was provided");
+  std::string FirstName = NormalizeNameForSpellingComparison(
+    Spellings.front()->getValueAsString("Name"));
+  for (std::vector<Record *>::const_iterator I = llvm::next(Spellings.begin()),
+       E = Spellings.end(); I != E; ++I) {
+    std::string Name = NormalizeNameForSpellingComparison(
+      (*I)->getValueAsString("Name"));
+    if (Name != FirstName)
+      return false;
+  }
+  return true;
+}
+
 namespace clang {
 
 // Emits the class definitions for attributes.
@@ -1153,7 +1189,58 @@ void EmitClangAttrClass(RecordKeeper &Re
 
     ae = Args.end();
 
-    OS << "\n public:\n";
+    OS << "\npublic:\n";
+
+    std::vector<Record *> Spellings = R.getValueAsListOfDefs("Spellings");
+
+    // If there are zero or one spellings, all spelling-related functionality
+    // can be elided. If all of the spellings share the same name, the spelling
+    // functionality can also be elided.
+    bool ElideSpelling = (Spellings.size() <= 1) ||
+                         SpellingNamesAreCommon(Spellings);
+
+    if (!ElideSpelling) {
+      OS << "  enum Spelling {\n";
+      for (std::vector<Record *>::const_iterator I = Spellings.begin(),
+           E = Spellings.end(); I != E; ++I) {
+        if (I != Spellings.begin())
+          OS << ",\n";
+        const Record &S = **I;
+        std::string Variety = S.getValueAsString("Variety");
+        std::string Spelling = S.getValueAsString("Name");
+        std::string Namespace = "";
+
+        if (Variety == "CXX11")
+          Namespace = S.getValueAsString("Namespace");
+
+        OS << "    " << Variety << "_";
+        if (!Namespace.empty())
+          OS << Namespace << "_";
+        OS << Spelling;
+      }
+      OS << "\n  };\n\n";
+    }
+
+    OS << "  static " << R.getName() << "Attr *CreateImplicit(";
+    OS << "ASTContext &Ctx";
+    if (!ElideSpelling)
+      OS << ", Spelling S";
+    for (ai = Args.begin(); ai != ae; ++ai) {
+      OS << ", ";
+      (*ai)->writeCtorParameters(OS);
+    }
+    OS << ", SourceRange Loc = SourceRange()";
+    OS << ") {\n";
+    OS << "    " << R.getName() << "Attr *A = new (Ctx) " << R.getName();
+    OS << "Attr(Loc, Ctx, ";
+    for (ai = Args.begin(); ai != ae; ++ai) {
+      (*ai)->writeImplicitCtorArgs(OS);
+      OS << ", ";
+    }
+    OS << (ElideSpelling ? "0" : "S") << ");\n";
+    OS << "    A->setImplicit(true);\n";
+    OS << "    return A;\n  }\n\n";
+
     OS << "  " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
     
     bool HasOpt = false;
@@ -1166,7 +1253,7 @@ void EmitClangAttrClass(RecordKeeper &Re
     }
 
     OS << "              , ";
-    OS << "unsigned SI = 0\n";
+    OS << "unsigned SI\n";
 
     OS << "             )\n";
     OS << "    : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
@@ -1198,7 +1285,7 @@ void EmitClangAttrClass(RecordKeeper &Re
       }
 
       OS << "              , ";
-      OS << "unsigned SI = 0\n";
+      OS << "unsigned SI\n";
 
       OS << "             )\n";
       OS << "    : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
@@ -1483,6 +1570,8 @@ void EmitClangAttrPCHRead(RecordKeeper &
     OS << "  case attr::" << R.getName() << ": {\n";
     if (R.isSubClassOf(InhClass))
       OS << "    bool isInherited = Record[Idx++];\n";
+    OS << "    bool isImplicit = Record[Idx++];\n";
+    OS << "    unsigned Spelling = Record[Idx++];\n";
     ArgRecords = R.getValueAsListOfDefs("Args");
     Args.clear();
     for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
@@ -1495,9 +1584,10 @@ void EmitClangAttrPCHRead(RecordKeeper &
       OS << ", ";
       (*ri)->writePCHReadArgs(OS);
     }
-    OS << ");\n";
+    OS << ", Spelling);\n";
     if (R.isSubClassOf(InhClass))
       OS << "    cast<InheritableAttr>(New)->setInherited(isInherited);\n";
+    OS << "    New->setImplicit(isImplicit);\n";
     OS << "    break;\n";
     OS << "  }\n";
   }
@@ -1527,6 +1617,9 @@ void EmitClangAttrPCHWrite(RecordKeeper
          << "Attr>(A);\n";
     if (R.isSubClassOf(InhClass))
       OS << "    Record.push_back(SA->isInherited());\n";
+    OS << "    Record.push_back(A->isImplicit());\n";
+    OS << "    Record.push_back(A->getSpellingListIndex());\n";
+
     for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
       createArgument(**ai, R.getName())->writePCHWrite(OS);
     OS << "    break;\n";
@@ -1806,7 +1899,7 @@ void EmitClangAttrTemplateInstantiate(Re
       OS << ", ";
       (*ai)->writeTemplateInstantiationArgs(OS);
     }
-    OS << ");\n    }\n";
+    OS << ", A->getSpellingListIndex());\n    }\n";
   }
   OS << "  } // end switch\n"
      << "  llvm_unreachable(\"Unknown attribute!\");\n"





More information about the cfe-commits mailing list