zahiraam updated this revision to Diff 142516.

https://reviews.llvm.org/D43576

Files:
  include/clang/AST/Decl.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/Attr.td
  include/clang/Basic/DeclNodes.td
  include/clang/Sema/AttributeList.h
  include/clang/Sema/Sema.h
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclCXX.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -322,12 +322,15 @@
         OS << "\" << get" << getUpperName() << "().getAsString() << \"";
       else if (type == "ParamIdx")
         OS << "\" << get" << getUpperName() << "().getSourceIndex() << \"";
-      else
+      else if (type == "DeclSpecUuidDecl *") {
+        OS << "\" << get" << getUpperName() << "() << \"";
+	} else
         OS << "\" << get" << getUpperName() << "() << \"";
     }
 
     void writeDump(raw_ostream &OS) const override {
-      if (type == "FunctionDecl *" || type == "NamedDecl *") {
+      if (type == "FunctionDecl *" || type == "NamedDecl *" ||
+	  (type == "DeclSpecUuidDecl *")) {
         OS << "    OS << \" \";\n";
         OS << "    dumpBareDeclRef(SA->get" << getUpperName() << "());\n"; 
       } else if (type == "IdentifierInfo *") {
@@ -1280,6 +1283,8 @@
     Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "ParamIdx");
   else if (ArgName == "VersionArgument")
     Ptr = llvm::make_unique<VersionArgument>(Arg, Attr);
+  else if (ArgName == "DeclSpecUuidDeclArgument")
+    Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "DeclSpecUuidDecl *");
 
   if (!Ptr) {
     // Search in reverse order so that the most-derived type is handled first.
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -535,6 +535,15 @@
   return Inst;
 }
 
+Decl *
+TemplateDeclInstantiator::VisitDeclSpecUuidDecl(DeclSpecUuidDecl *D) {
+  DeclSpecUuidDecl *Inst = DeclSpecUuidDecl::Create(SemaRef.Context, Owner,
+                                                    D->getLocation(),
+                                                    D->getStrUuid());
+  Owner->addDecl(Inst);
+  return Inst;
+}
+
 Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
                                                            bool IsTypeAlias) {
   bool Invalid = false;
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -573,7 +573,7 @@
       return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
     if (UuidAttrs.size() > 1)
       return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
-    UuidStr = UuidAttrs.back()->getGuid();
+    UuidStr = UuidAttrs.back()->getDeclSpecUuidDecl()->getStrUuid();
   }
 
   return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UuidStr,
@@ -596,7 +596,8 @@
         return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
       if (UuidAttrs.size() > 1)
         return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
-      UuidStr = UuidAttrs.back()->getGuid();
+      UuidStr = UuidAttrs.back()->getDeclSpecUuidDecl()->getStrUuid();
+
     }
   }
 
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -4930,14 +4930,10 @@
 //===----------------------------------------------------------------------===//
 
 UuidAttr *Sema::mergeUuidAttr(Decl *D, SourceRange Range,
-                              unsigned AttrSpellingListIndex, StringRef Uuid) {
-  if (const auto *UA = D->getAttr<UuidAttr>()) {
-    if (UA->getGuid().equals_lower(Uuid))
-      return nullptr;
-    Diag(UA->getLocation(), diag::err_mismatched_uuid);
-    Diag(Range.getBegin(), diag::note_previous_uuid);
-    D->dropAttr<UuidAttr>();
-  }
+                              unsigned AttrSpellingListIndex,
+                              DeclSpecUuidDecl *Uuid) {
+  if (D->getAttr<UuidAttr>())
+    return nullptr;
 
   return ::new (Context) UuidAttr(Range, Context, Uuid, AttrSpellingListIndex);
 }
@@ -4949,9 +4945,9 @@
     return;
   }
 
-  StringRef StrRef;
-  SourceLocation LiteralLoc;
-  if (!S.checkStringLiteralArgumentAttr(AL, 0, StrRef, &LiteralLoc))
+  StringRef  StrRef = AL.getUuidDecl()->getStrUuid();
+  SourceLocation LiteralLoc = AL.getLoc();
+  if (StrRef.empty())
     return;
 
   // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
@@ -4987,7 +4983,9 @@
     S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
 
   UuidAttr *UA = S.mergeUuidAttr(D, AL.getRange(),
-                                 AL.getAttributeSpellingListIndex(), StrRef);
+				 AL.getAttributeSpellingListIndex(),
+				 AL.getUuidDecl());
+
   if (UA)
     D->addAttr(UA);
 }
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2495,7 +2495,7 @@
     NewAttr = nullptr;
   else if (const auto *UA = dyn_cast<UuidAttr>(Attr))
     NewAttr = S.mergeUuidAttr(D, UA->getRange(), AttrSpellingListIndex,
-                              UA->getGuid());
+                              UA->getDeclSpecUuidDecl());
   else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
     NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
 
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -556,7 +556,32 @@
     T.skipToEnd();
     return !HasInvalidAccessor;
   }
-
+  if (AttrName->getName() == "uuid") {
+    // Parse the uuid attribute and create a UuidDecl.
+    ConsumeParen();
+    assert(Tok.is(tok::string_literal) && "uuid not followed by string literal '('");
+    int sz = Tok.getLength();
+    SmallString<8> UuidBuffer;
+    bool Invalid = false;
+    StringRef UuidStr = PP.getSpelling(Tok, UuidBuffer, &Invalid);
+
+    // Clean up the string from the "\" at begining and at end.
+    StringRef UuidStr1 = UuidStr.ltrim('\"');
+    StringRef TrimmedUuidStr = UuidStr1.rtrim('\"');
+    DeclSpecUuidDecl *ArgDecl =
+      DeclSpecUuidDecl::Create(Actions.getASTContext(),
+                               Actions.getFunctionLevelDeclContext(),
+                               SourceLocation(),
+                               TrimmedUuidStr);
+
+    // Advance to next token. Should be a r-paren.
+    PP.Lex(Tok);
+    SourceLocation RParen = Tok.getLocation();
+    SourceRange attrRange = SourceRange(AttrNameLoc, RParen);
+    if (!ExpectAndConsume(tok::r_paren))
+      Attrs.addNew(AttrName, attrRange, nullptr, AttrNameLoc, ArgDecl, AttributeList::AS_Declspec);
+    return true;
+  }
   unsigned NumArgs =
       ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,
                                SourceLocation(), AttributeList::AS_Declspec);
@@ -911,6 +936,7 @@
   enum { Introduced, Deprecated, Obsoleted, Unknown };
   AvailabilityChange Changes[Unknown];
   ExprResult MessageExpr, ReplacementExpr;
+  Decl *DeclSpecUuidDecl = nullptr;
 
   // Opening '('.
   BalancedDelimiterTracker T(*this, tok::l_paren);
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -1724,9 +1724,9 @@
   if (Uuid && isStruct() && !getDeclContext()->isExternCContext() &&
       !isDeclContextInNamespace(getDeclContext()) &&
       ((getName() == "IUnknown" &&
-        Uuid->getGuid() == "00000000-0000-0000-C000-000000000046") ||
+        Uuid->getDeclSpecUuidDecl()->getStrUuid() == "00000000-0000-0000-C000-000000000046") ||
        (getName() == "IDispatch" &&
-        Uuid->getGuid() == "00020400-0000-0000-C000-000000000046"))) {
+        Uuid->getDeclSpecUuidDecl()->getStrUuid() == "00020400-0000-0000-C000-000000000046"))) {
     if (getNumBases() > 0)
       return false;
     return true;
Index: lib/AST/DeclBase.cpp
===================================================================
--- lib/AST/DeclBase.cpp
+++ lib/AST/DeclBase.cpp
@@ -810,6 +810,7 @@
     case OMPThreadPrivate:
     case OMPCapturedExpr:
     case Empty:
+    case DeclSpecUuid:
       // Never looked up by name.
       return 0;
   }
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -4553,3 +4553,14 @@
 ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
   return new (C, ID) ExportDecl(nullptr, SourceLocation());
 }
+
+//===----------------------------------------------------------------------===//
+// UuidDeclSpec Implementation
+//===----------------------------------------------------------------------===//
+
+DeclSpecUuidDecl * DeclSpecUuidDecl::Create(const ASTContext &C, DeclContext *DC,
+                                            SourceLocation IdLoc,
+                                            StringRef UuidVal)
+{
+  return new (C, DC) DeclSpecUuidDecl(DeclSpecUuid, DC, IdLoc, UuidVal);
+}
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2417,7 +2417,7 @@
                                       VisibilityAttr::VisibilityType Vis,
                                       unsigned AttrSpellingListIndex);
   UuidAttr *mergeUuidAttr(Decl *D, SourceRange Range,
-                          unsigned AttrSpellingListIndex, StringRef Uuid);
+                          unsigned AttrSpellingListIndex, DeclSpecUuidDecl *Uuid);
   DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range,
                                     unsigned AttrSpellingListIndex);
   DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
Index: include/clang/Sema/AttributeList.h
===================================================================
--- include/clang/Sema/AttributeList.h
+++ include/clang/Sema/AttributeList.h
@@ -35,6 +35,7 @@
 class Expr;
 class IdentifierInfo;
 class LangOptions;
+class DeclSpecUuidDecl;
 
 /// \brief Represents information about a change in availability for
 /// an entity, which is part of the encoding of the 'availability'
@@ -181,6 +182,8 @@
   
   const Expr *MessageExpr;
 
+  DeclSpecUuidDecl *UuidDecl;
+
   /// The next attribute in the current position.
   AttributeList *NextInPosition = nullptr;
 
@@ -321,6 +324,16 @@
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
 
+  /// Constructor for __declspec(uuid) attribute.
+  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+		IdentifierInfo *scopeName, SourceLocation scopeLoc,
+		DeclSpecUuidDecl *uuid, AttributeList::Syntax syntaxUsed)
+    : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+      ScopeLoc(scopeLoc), Invalid(false), HasParsedType(false),
+      SyntaxUsed(syntaxUsed), NumArgs(1), UuidDecl(uuid) {
+    AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+  }
+
   /// Type tag information is stored immediately following the arguments, if
   /// any, at the end of the object.  They are mutually exclusive with
   /// availability slots.
@@ -524,6 +537,11 @@
     return getPropertyDataBuffer();
   }
 
+  DeclSpecUuidDecl *getUuidDecl() const {
+    assert(getKind() == AT_Uuid && "Not an availability attribute");
+    return UuidDecl;
+  }
+
   /// \brief Get an index into the attribute spelling list
   /// defined in Attr.td. This index is used by an attribute
   /// to pretty print itself.
@@ -577,6 +595,10 @@
     PropertyAllocSize =
       sizeof(AttributeList)
       + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
+        / sizeof(void*) * sizeof(void*),
+    UuidDeclSpecSize =
+      sizeof(AttributeList)
+      + (sizeof(DeclSpecUuidDecl) + sizeof(void *) + sizeof(ArgsUnion) - 1)
         / sizeof(void*) * sizeof(void*)
   };
 
@@ -744,6 +766,15 @@
                                           getterId, setterId,
                                           syntaxUsed));
   }
+
+  AttributeList *
+  createUuidDeclSpecAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+                              IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                              DeclSpecUuidDecl *ArgDecl, AttributeList::Syntax syntaxUsed) {
+    void *memory = allocate(sizeof(AttributeList));
+    return add(new (memory) AttributeList(attrName, attrRange,
+                                          scopeName, scopeLoc, ArgDecl, syntaxUsed));
+  }
 };
 
 /// ParsedAttributes - A collection of parsed attributes.  Currently
@@ -898,6 +929,18 @@
     return attr;
   }
 
+  /// Add microsoft __delspec(uuid) attribute.
+  AttributeList *
+  addNew(IdentifierInfo *attrName, SourceRange attrRange,
+	 IdentifierInfo *scopeName, SourceLocation scopeLoc,
+	 DeclSpecUuidDecl *ArgDecl, AttributeList::Syntax syntaxUsed) {
+    AttributeList *attr =
+      pool.createUuidDeclSpecAttribute(attrName, attrRange, scopeName,
+				       scopeLoc, ArgDecl, syntaxUsed);
+    add(attr);
+    return attr;
+  }
+
 private:
   mutable AttributePool pool;
   AttributeList *list = nullptr;
Index: include/clang/Basic/DeclNodes.td
===================================================================
--- include/clang/Basic/DeclNodes.td
+++ include/clang/Basic/DeclNodes.td
@@ -98,4 +98,5 @@
 def Import : Decl;
 def OMPThreadPrivate : Decl;
 def Empty : Decl;
+def DeclSpecUuid : Decl;
 
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -172,6 +172,8 @@
 // Like VariadicUnsignedArgument except values are ParamIdx.
 class VariadicParamIdxArgument<string name> : Argument<name, 1>;
 
+class DeclSpecUuidDeclArgument<string name, bit opt = 0> : Argument<name,opt>;
+
 // Like VariadicParamIdxArgument but for a single function parameter index.
 class ParamIdxArgument<string name, bit opt = 0> : Argument<name, opt>;
 
@@ -2016,7 +2018,7 @@
 
 def Uuid : InheritableAttr {
   let Spellings = [Declspec<"uuid">, Microsoft<"uuid">];
-  let Args = [StringArgument<"Guid">];
+  let Args = [DeclSpecUuidDeclArgument<"DeclSpecUuidDecl">];
   let Subjects = SubjectList<[Record, Enum]>;
   // FIXME: Allow expressing logical AND for LangOpts. Our condition should be:
   // CPlusPlus && (MicrosoftExt || Borland)
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -1416,6 +1416,8 @@
 
 DEF_TRAVERSE_DECL(EmptyDecl, {})
 
+DEF_TRAVERSE_DECL(DeclSpecUuidDecl, {})
+
 DEF_TRAVERSE_DECL(FileScopeAsmDecl,
                   { TRY_TO(TraverseStmt(D->getAsmString())); })
 
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -75,6 +75,7 @@
 class TypeLoc;
 class UnresolvedSetImpl;
 class VarTemplateDecl;
+class DeclSpecUuidDecl;
 
 /// A container of type source information.
 ///
@@ -4238,6 +4239,22 @@
   static bool classofKind(Kind K) { return K == Empty; }
 };
 
+class DeclSpecUuidDecl : public Decl {
+  StringRef StrUuid;
+public:
+  static DeclSpecUuidDecl *Create(const ASTContext &C, DeclContext *DC,
+                                  SourceLocation IdLoc,
+                                  StringRef UuidVal);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == DeclSpecUuid; }
+
+  DeclSpecUuidDecl(Kind DK, DeclContext *DC, SourceLocation IdLoc, StringRef UuidVal)
+    : Decl (DK, DC, IdLoc), StrUuid(UuidVal) {}
+
+  StringRef getStrUuid() { return StrUuid; }
+};
+
 /// Insertion operator for diagnostics.  This allows sending NamedDecl's
 /// into a diagnostic with <<.
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D43576: S... Zahira Ammarguellat via Phabricator via cfe-commits
    • [PATCH] D435... Zahira Ammarguellat via Phabricator via cfe-commits
    • [PATCH] D435... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D435... Zahira Ammarguellat via Phabricator via cfe-commits
    • [PATCH] D435... Zahira Ammarguellat via Phabricator via cfe-commits
    • [PATCH] D435... Zahira Ammarguellat via Phabricator via cfe-commits
    • [PATCH] D435... Zahira Ammarguellat via Phabricator via cfe-commits
    • [PATCH] D435... Zahira Ammarguellat via Phabricator via cfe-commits

Reply via email to