zahiraam updated this revision to Diff 193258.
zahiraam marked 15 inline comments as done.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D43576/new/

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/ParsedAttr.h
  include/clang/Sema/Sema.h
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclCXX.cpp
  lib/CodeGen/CGDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTCommon.cpp
  test/Parser/MicrosoftExtensions.cpp
  test/Sema/ms-uuid-1.cpp
  test/Sema/ms-uuid-2.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -321,12 +321,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 *") {
@@ -1296,6 +1299,8 @@
     Ptr = llvm::make_unique<VariadicIdentifierArgument>(Arg, Attr);
   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: test/Sema/ms-uuid-2.cpp
===================================================================
--- /dev/null
+++ test/Sema/ms-uuid-2.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions -fms-compatibility -std=c++14  %s
+
+
+typedef struct _GUID
+{
+    unsigned long  Data1;
+    unsigned short Data2;
+    unsigned short Data3;
+    unsigned char  Data4[8];
+} GUID;
+
+// expected-error@+5 {{C++ requires a type specifier for all declarations}}
+// expected-error@+4 {{invalid digit 'a' in decimal constant}}
+// expected-error@+3 {{use of undeclared identifier 'def0'}}
+// expected-error@+2 {{invalid digit 'a' in decimal constant}}
+// expected-error@+1 {{expected ';' after top level declarator}}
+uuid(12345678-9abc-def0-1234-56789abcdef0) struct S2;
+
Index: test/Sema/ms-uuid-1.cpp
===================================================================
--- /dev/null
+++ test/Sema/ms-uuid-1.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions -fms-compatibility -std=c++14 %s
+// expected-no-diagnostics
+typedef struct _GUID {
+  int i;
+} IID;
+template <const IID *piid>
+class A {};
+
+struct
+    __declspec(uuid("{DDB47A6A-0F23-11D5-9109-00E0296B75D3}"))
+        S1 {};
+
+struct
+    __declspec(uuid("{DDB47A6A-0F23-11D5-9109-00E0296B75D3}"))
+        S2 {};
+
+struct __declspec(dllexport)
+    C1 : public A<&__uuidof(S1)> {};
+
+struct __declspec(dllexport)
+    C2 : public A<&__uuidof(S2)> {};
+int printf(const char *, ...);
+int main() {
+
+  if (&__uuidof(S1) == &__uuidof(S2))
+    printf("OK\n");
+  else
+    printf("ERROR\n");
+
+  return 0;
+}
Index: test/Parser/MicrosoftExtensions.cpp
===================================================================
--- test/Parser/MicrosoftExtensions.cpp
+++ test/Parser/MicrosoftExtensions.cpp
@@ -76,7 +76,7 @@
    struct_with_uuid var_with_uuid[1];
    struct_without_uuid var_without_uuid[1];
 
-   __uuidof(struct_with_uuid);
+   __uuidof(struct_with_uuid); // expected-error {{non-type template argument of type 'const _GUID' is not a constant expression}}
    __uuidof(struct_with_uuid2);
    __uuidof(struct_with_uuid3);
    __uuidof(struct_without_uuid); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
@@ -137,7 +137,7 @@
 
 COM_CLASS_TEMPLATE_REF<int, __uuidof(struct_with_uuid)> good_template_arg;
 
-COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg; // expected-error {{non-type template argument of type 'const _GUID' is not a constant expression}}
+COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg;
 
 namespace PR16911 {
 struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
Index: lib/Serialization/ASTCommon.cpp
===================================================================
--- lib/Serialization/ASTCommon.cpp
+++ lib/Serialization/ASTCommon.cpp
@@ -348,6 +348,7 @@
   case Decl::ObjCProtocol:
   case Decl::ObjCInterface:
   case Decl::Empty:
+  case Decl::DeclSpecUuid:
     return true;
 
   // Never redeclarable.
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -606,6 +606,11 @@
   return Inst;
 }
 
+ Decl *
+ TemplateDeclInstantiator::VisitDeclSpecUuidDecl(DeclSpecUuidDecl *D) {
+   llvm_unreachable("DeclSpecUuidDecl cannot be instantiated");
+}
+
 Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
                                                            bool IsTypeAlias) {
   bool Invalid = false;
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -615,25 +615,74 @@
   }
 }
 
-/// Build a Microsoft __uuidof expression with a type operand.
-ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
-                                SourceLocation TypeidLoc,
-                                TypeSourceInfo *Operand,
-                                SourceLocation RParenLoc) {
-  StringRef UuidStr;
-  if (!Operand->getType()->isDependentType()) {
-    llvm::SmallSetVector<const UuidAttr *, 1> UuidAttrs;
-    getUuidAttrOfType(*this, Operand->getType(), UuidAttrs);
-    if (UuidAttrs.empty())
-      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();
-  }
+ /// Finds the __declSpec uuid Decl off a type.
+ static void FindADeclOffAType(Sema &SemaRef,
+                               QualType QT,
+                               llvm::SmallVector<const Decl *, 1> &UuidDecl) {
+   const Type *Ty = QT.getTypePtr();
+   const Decl *dcl;
+   if (QT->isPointerType() || QT->isReferenceType())
+     Ty = QT->getPointeeType().getTypePtr();
+   else if (QT->isArrayType())
+     Ty = Ty->getBaseElementTypeUnsafe();
+
+   const auto *TD = Ty->getAsTagDecl();
+   if (!TD) {
+     return;
+   }
+   dcl = TD->getMostRecentDecl();
+   if (TD->getMostRecentDecl()->getAttr<UuidAttr>()) {
+     UuidDecl.push_back(dcl);
+     return;
+   }
+
+   if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(TD)) {
+     const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
+     for (const TemplateArgument &TA : TAL.asArray()) {
+       const Decl *dd = nullptr;
+       if (TA.getKind() == TemplateArgument::Type)
+         FindADeclOffAType(SemaRef, TA.getAsType(), UuidDecl);
+       else if (TA.getKind() == TemplateArgument::Declaration)
+         FindADeclOffAType(SemaRef, TA.getAsType(), UuidDecl);
+       if (dd)
+         UuidDecl.push_back(dcl);
+     }
+   }
+ }
 
-  return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UuidStr,
-                                     SourceRange(TypeidLoc, RParenLoc));
-}
+
+/// Build a Microsoft __uuidof expression with a type operand.
+ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
+   SourceLocation TypeidLoc,
+   TypeSourceInfo *Operand,
+   SourceLocation RParenLoc) {
+   StringRef UuidStr;
+   if (!Operand->getType()->isDependentType()) {
+     QualType QT = Operand->getType();
+     llvm::SmallVector<const Decl *, 1> UuidDecl;
+     FindADeclOffAType(*this, QT, UuidDecl);
+     if (UuidDecl.empty())
+       return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
+     if (UuidDecl.size() > 1)
+       return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
+     const Decl *dd1 = UuidDecl.back();
+     auto *A = dd1->getAttr<UuidAttr>();
+     UuidStr = A->getUuidAsStr();
+   }
+
+   ExprResult expr = UuidExpMap[UuidStr].get();
+   ExprResult uuid_expr;
+   if (expr.isUnset()) {
+     uuid_expr =
+       new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UuidStr,
+         SourceRange(TypeidLoc, RParenLoc));
+     UuidExpMap[UuidStr] = uuid_expr;
+     return uuid_expr;
+   }
+   else {
+     return expr;
+   }
+ }
 
 /// Build a Microsoft __uuidof expression with an expression operand.
 ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
@@ -651,7 +700,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();
     }
   }
 
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -5399,9 +5399,11 @@
 //===----------------------------------------------------------------------===//
 
 UuidAttr *Sema::mergeUuidAttr(Decl *D, SourceRange Range,
-                              unsigned AttrSpellingListIndex, StringRef Uuid) {
-  if (const auto *UA = D->getAttr<UuidAttr>()) {
-    if (UA->getGuid().equals_lower(Uuid))
+                              unsigned AttrSpellingListIndex,
+                              DeclSpecUuidDecl *Uuid) {
+  if (auto *UA = D->getAttr<UuidAttr>()) {
+    if (UA->UuidAttr::getUuidAsStr().equals_lower(Uuid->getStrUuid()) &&
+        declaresSameEntity(DeclToDeclSpecUuidDecl.find(D)->first, D))
       return nullptr;
     Diag(UA->getLocation(), diag::err_mismatched_uuid);
     Diag(Range.getBegin(), diag::note_previous_uuid);
@@ -5420,8 +5422,13 @@
 
   StringRef StrRef;
   SourceLocation LiteralLoc;
-  if (!S.checkStringLiteralArgumentAttr(AL, 0, StrRef, &LiteralLoc))
-    return;
+  StrRef = AL.getUuidStr();
+  if (!StrRef.empty())
+    LiteralLoc = AL.getLoc();
+  else {
+    if (!S.checkStringLiteralArgumentAttr(AL, 0, StrRef, &LiteralLoc))
+      return;
+  }
 
   // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
   // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
@@ -5455,8 +5462,14 @@
   if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
     S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
 
+  DeclSpecUuidDecl *ArgDecl;
+  ArgDecl = DeclSpecUuidDecl::Create(S.getASTContext(), S.getFunctionLevelDeclContext(),
+                                     SourceLocation(), StrRef);
+
+  S.DeclToDeclSpecUuidDecl[D] = ArgDecl;
+
   UuidAttr *UA = S.mergeUuidAttr(D, AL.getRange(),
-                                 AL.getAttributeSpellingListIndex(), StrRef);
+                                 AL.getAttributeSpellingListIndex(), ArgDecl);
   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 (const auto *SLHA = dyn_cast<SpeculativeLoadHardeningAttr>(Attr))
     NewAttr = S.mergeSpeculativeLoadHardeningAttr(D, *SLHA);
   else if (const auto *SLHA = dyn_cast<NoSpeculativeLoadHardeningAttr>(Attr))
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -4160,6 +4160,7 @@
       return;
     ArgExprs.push_back(StringResult.get());
   } else {
+
     // something like uuid({000000A0-0000-0000-C000-000000000049}) -- no
     // quotes in the parens. Just append the spelling of all tokens encountered
     // until the closing paren.
Index: lib/CodeGen/CGDecl.cpp
===================================================================
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -107,6 +107,7 @@
   case Decl::OMPCapturedExpr:
   case Decl::OMPRequires:
   case Decl::Empty:
+  case Decl::DeclSpecUuid:
     // None of these decls require codegen support.
     return;
 
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -1769,16 +1769,16 @@
       return false;
 
   // Check "Special" types.
-  const auto *Uuid = getAttr<UuidAttr>();
+  auto *Uuid = getAttr<UuidAttr>();
   // MS SDK declares IUnknown/IDispatch both in the root of a TU, or in an
   // extern C++ block directly in the TU.  These are only valid if in one
   // of these two situations.
   if (Uuid && isStruct() && !getDeclContext()->isExternCContext() &&
       !isDeclContextInNamespace(getDeclContext()) &&
       ((getName() == "IUnknown" &&
-        Uuid->getGuid() == "00000000-0000-0000-C000-000000000046") ||
+        Uuid->UuidAttr::getUuidAsStr() == "00000000-0000-0000-C000-000000000046") ||
        (getName() == "IDispatch" &&
-        Uuid->getGuid() == "00020400-0000-0000-C000-000000000046"))) {
+         Uuid->UuidAttr::getUuidAsStr() == "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
@@ -815,6 +815,7 @@
     case OMPAllocate:
     case OMPRequires:
     case OMPCapturedExpr:
+    case DeclSpecUuid:
     case Empty:
       // Never looked up by name.
       return 0;
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -4716,3 +4716,13 @@
 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
@@ -405,6 +405,12 @@
   /// Source location for newly created implicit MSInheritanceAttrs
   SourceLocation ImplicitMSInheritanceAttrLoc;
 
+  /// Map from a uuid string to an expr. Each uuid string is mapped to
+  /// a single Expr.
+  llvm::StringMap <ExprResult> UuidExpMap;
+
+  std::map<const Decl*, DeclSpecUuidDecl*> DeclToDeclSpecUuidDecl;
+
   /// pragma clang section kind
   enum PragmaClangSectionKind {
     PCSK_Invalid      = 0,
@@ -2548,7 +2554,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/ParsedAttr.h
===================================================================
--- include/clang/Sema/ParsedAttr.h
+++ include/clang/Sema/ParsedAttr.h
@@ -36,6 +36,7 @@
 class Expr;
 class IdentifierInfo;
 class LangOptions;
+class DeclSpecUuidDecl;
 
 /// Represents information about a change in availability for
 /// an entity, which is part of the encoding of the 'availability'
@@ -216,6 +217,8 @@
 
   const Expr *MessageExpr;
 
+  StringRef StrUuid;
+
   ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); }
   ArgsUnion const *getArgsBuffer() const {
     return getTrailingObjects<ArgsUnion>();
@@ -331,6 +334,16 @@
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
 
+  /// Constructor for __declspec(uuid) attribute.
+  ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+             IdentifierInfo *scopeName, SourceLocation scopeLoc,
+             StringRef struuid, ParsedAttr::Syntax syntaxUsed)
+      : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+        ScopeLoc(scopeLoc), Invalid(false), HasParsedType(false),
+        SyntaxUsed(syntaxUsed), NumArgs(1), StrUuid(struuid) {
+    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.
@@ -547,6 +560,11 @@
     return getPropertyDataBuffer().SetterId;
   }
 
+  StringRef getUuidStr() const {
+    assert(getKind() == AT_Uuid && "Not an uuid attribute");
+    return StrUuid;
+  }
+
   /// Get an index into the attribute spelling list
   /// defined in Attr.td. This index is used by an attribute
   /// to pretty print itself.
@@ -782,6 +800,15 @@
     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
                                        getterId, setterId, syntaxUsed));
   }
+
+  ParsedAttr *
+  createUuidDeclSpecAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+                              IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                              StringRef struuid, ParsedAttr::Syntax syntaxUsed) {
+    void *memory = allocate(sizeof(ParsedAttr));
+    return add(new (memory) ParsedAttr(attrName, attrRange, scopeName,
+                                          scopeLoc, struuid, syntaxUsed));
+  }
 };
 
 class ParsedAttributesView {
@@ -974,6 +1001,16 @@
     return attr;
   }
 
+  /// Add microsoft __delspec(uuid) attribute.
+  ParsedAttr *
+  addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName,
+         SourceLocation scopeLoc, StringRef struuid, ParsedAttr::Syntax syntaxUsed) {
+    ParsedAttr *attr =
+        pool.createUuidDeclSpecAttribute(attrName, attrRange, scopeName, scopeLoc,
+                                         struuid, syntaxUsed);
+    addAtEnd(attr);
+    return attr;
+  }
 private:
   mutable AttributePool pool;
 };
Index: include/clang/Basic/DeclNodes.td
===================================================================
--- include/clang/Basic/DeclNodes.td
+++ include/clang/Basic/DeclNodes.td
@@ -101,4 +101,4 @@
 def OMPAllocate : Decl;
 def OMPRequires : Decl;
 def Empty : Decl;
-
+def DeclSpecUuid : Decl;
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -179,6 +179,8 @@
 class VariadicStringArgument<string name> : Argument<name, 1>;
 class VariadicIdentifierArgument<string name> : Argument<name, 1>;
 
+class DeclSpecUuidDeclArgument<string name, bit opt = 0> : Argument<name,opt>;
+
 // Like VariadicUnsignedArgument except values are ParamIdx.
 class VariadicParamIdxArgument<string name> : Argument<name, 1>;
 
@@ -2232,12 +2234,15 @@
 
 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)
   let LangOpts = [MicrosoftExt, Borland];
   let Documentation = [Undocumented];
+  let AdditionalMembers = [{
+   StringRef getUuidAsStr() { return getDeclSpecUuidDecl()->getStrUuid(); }
+  }];
 }
 
 def VectorSize : TypeAttr {
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -1427,6 +1427,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.
 ///
@@ -4276,6 +4277,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
https://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... Reid Kleckner 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

Reply via email to