zahiraam updated this revision to Diff 200484.

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/CodeGen/CodeGenModule.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTCommon.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,9 @@
     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: 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
@@ -630,6 +630,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
@@ -628,11 +628,12 @@
       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()->getSTLUuid()->getString();
   }
 
   return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UuidStr,
                                      SourceRange(TypeidLoc, RParenLoc));
+
 }
 
 /// Build a Microsoft __uuidof expression with an expression operand.
@@ -651,7 +652,9 @@
         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()->getSTLUuid()->getString();
+      if (UuidStr.startswith("{") && UuidStr.endswith("}"))
+        UuidStr = UuidStr.drop_front().drop_back();
     }
   }
 
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -5399,9 +5399,12 @@
 //===----------------------------------------------------------------------===//
 
 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->getDeclSpecUuidDecl()->getSTLUuid()->getString().equals_lower(
+            Uuid->getSTLUuid()->getString()) &&
+        declaresSameEntity(DeclToDeclSpecUuidDecl.find(D)->first, D))
       return nullptr;
     Diag(UA->getLocation(), diag::err_mismatched_uuid);
     Diag(Range.getBegin(), diag::note_previous_uuid);
@@ -5446,6 +5449,16 @@
     }
   }
 
+  QualType ResTy;
+  StringLiteral *Stl = nullptr;
+  llvm::APInt Length(32, StrRef.size() + 1);
+  ResTy = S.getASTContext().adjustStringLiteralBaseType(
+      S.getASTContext().WideCharTy.withConst());
+  ResTy = S.getASTContext().getConstantArrayType(ResTy, Length,
+                                                 ArrayType::Normal, 0);
+  Stl = StringLiteral::Create(S.getASTContext(), StrRef, StringLiteral::Ascii,
+                              0, ResTy, LiteralLoc);
+
   // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
   // the only thing in the [] list, the [] too), and add an insertion of
   // __declspec(uuid(...)).  But sadly, neither the SourceLocs of the commas
@@ -5455,8 +5468,15 @@
   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(), Stl);
+
+  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
@@ -2515,7 +2515,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/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1068,6 +1068,9 @@
         FD->hasAttr<CUDAGlobalAttr>())
       MangledName = MangledName + ".stub";
 
+  const auto ExistingRecord = Manglings.find(MangledName);
+  if (ExistingRecord != std::end(Manglings))
+    Manglings.remove(&(*ExistingRecord));
   auto Result = Manglings.insert(std::make_pair(MangledName, GD));
   return MangledDeclNames[CanonicalGD] = Result.first->first();
 }
@@ -2999,7 +3002,6 @@
       Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
       setDSOLocal(Entry);
     }
-
     // If there are two attempts to define the same mangled name, issue an
     // error.
     if (IsForDefinition && !Entry->isDeclaration()) {
Index: lib/CodeGen/CGDecl.cpp
===================================================================
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -108,6 +108,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
@@ -1793,9 +1793,11 @@
   if (Uuid && isStruct() && !getDeclContext()->isExternCContext() &&
       !isDeclContextInNamespace(getDeclContext()) &&
       ((getName() == "IUnknown" &&
-        Uuid->getGuid() == "00000000-0000-0000-C000-000000000046") ||
+        Uuid->getDeclSpecUuidDecl()->getSTLUuid()->getString() ==
+          "00000000-0000-0000-C000-000000000046") ||
        (getName() == "IDispatch" &&
-        Uuid->getGuid() == "00020400-0000-0000-C000-000000000046"))) {
+        Uuid->getDeclSpecUuidDecl()->getSTLUuid()->getString() ==
+               "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
@@ -800,6 +800,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
@@ -4805,3 +4805,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,
+                                            StringLiteral *stluuid) {
+   return new (C, DC) DeclSpecUuidDecl(DeclSpecUuid, DC, IdLoc, stluuid);
+ }
+
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -405,6 +405,8 @@
   /// Source location for newly created implicit MSInheritanceAttrs
   SourceLocation ImplicitMSInheritanceAttrLoc;
 
+  std::map<const Decl*, DeclSpecUuidDecl*> DeclToDeclSpecUuidDecl;
+
   /// pragma clang section kind
   enum PragmaClangSectionKind {
     PCSK_Invalid      = 0,
@@ -2578,7 +2580,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'
@@ -333,6 +334,16 @@
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
 
+  /// Constructor for __declspec(uuid) attribute.
+  ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+             IdentifierInfo *scopeName, SourceLocation scopeLoc,
+             StringLiteral *stluuid, ParsedAttr::Syntax syntaxUsed)
+      : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+        ScopeLoc(scopeLoc), Invalid(false), HasParsedType(false),
+    SyntaxUsed(syntaxUsed), NumArgs(1) {
+    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.
@@ -806,6 +817,15 @@
     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
                                        getterId, setterId, syntaxUsed));
   }
+
+  ParsedAttr *
+  createUuidDeclSpecAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+                              IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                              StringLiteral *stluuid, ParsedAttr::Syntax syntaxUsed) {
+    void *memory = allocate(sizeof(ParsedAttr));
+    return add(new (memory) ParsedAttr(attrName, attrRange, scopeName,
+                                       scopeLoc, stluuid, syntaxUsed));
+  }
 };
 
 class ParsedAttributesView {
@@ -905,6 +925,7 @@
 /// is that this will become significantly more serious.
 class ParsedAttributes : public ParsedAttributesView {
 public:
+
   ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
   ParsedAttributes(const ParsedAttributes &) = delete;
 
@@ -1005,6 +1026,17 @@
     return attr;
   }
 
+  /// Add microsoft __delspec(uuid) attribute.
+  ParsedAttr *
+  addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName,
+         SourceLocation scopeLoc, StringLiteral *stluuid, ParsedAttr::Syntax syntaxUsed) {
+    ParsedAttr *attr =
+        pool.createUuidDeclSpecAttribute(attrName, attrRange, scopeName, scopeLoc,
+                                         stluuid, 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,5 @@
 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
@@ -180,6 +180,7 @@
 class VariadicExprArgument<string name> : Argument<name, 1>;
 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>;
@@ -2238,7 +2239,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
@@ -1433,6 +1433,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.
 ///
@@ -4284,6 +4285,24 @@
   static bool classofKind(Kind K) { return K == Empty; }
 };
 
+class DeclSpecUuidDecl : public Decl {
+  StringLiteral *STLUuid;
+public:
+  static DeclSpecUuidDecl *Create(const ASTContext &C, DeclContext *DC,
+                                  SourceLocation IdLoc,
+                                  StringLiteral *stluuid);
+
+
+   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,
+                    StringLiteral *stluuid)
+       : Decl (DK, DC, IdLoc), STLUuid(stluuid) {}
+
+   StringLiteral *getSTLUuid() { return STLUuid; }
+};
+
 /// 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... 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