Fix serialization/deserialization for __uuidof
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 28 Mar 2016 03:19:50 +0000 (03:19 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 28 Mar 2016 03:19:50 +0000 (03:19 +0000)
I broke this back in r264529 because I forgot to serialize the UuidAttr
member.  Fix this by replacing the UuidAttr with a StringRef which is
properly serialized and deserialized.

llvm-svn: 264562

clang/include/clang/AST/ExprCXX.h
clang/lib/AST/ExprCXX.cpp
clang/lib/AST/MicrosoftMangle.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/test/PCH/uuidof.cpp [new file with mode: 0644]

index af4f9e3..adb5b18 100644 (file)
@@ -778,23 +778,23 @@ public:
 class CXXUuidofExpr : public Expr {
 private:
   llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
-  const UuidAttr *UA;
+  StringRef UuidStr;
   SourceRange Range;
 
 public:
-  CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, const UuidAttr *UA,
+  CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, StringRef UuidStr,
                 SourceRange R)
       : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false,
              Operand->getType()->isDependentType(),
              Operand->getType()->isInstantiationDependentType(),
              Operand->getType()->containsUnexpandedParameterPack()),
-        Operand(Operand), UA(UA), Range(R) {}
+        Operand(Operand), UuidStr(UuidStr), Range(R) {}
 
-  CXXUuidofExpr(QualType Ty, Expr *Operand, const UuidAttr *UA, SourceRange R)
+  CXXUuidofExpr(QualType Ty, Expr *Operand, StringRef UuidStr, SourceRange R)
       : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false,
              Operand->isTypeDependent(), Operand->isInstantiationDependent(),
              Operand->containsUnexpandedParameterPack()),
-        Operand(Operand), UA(UA), Range(R) {}
+        Operand(Operand), UuidStr(UuidStr), Range(R) {}
 
   CXXUuidofExpr(EmptyShell Empty, bool isExpr)
     : Expr(CXXUuidofExprClass, Empty) {
@@ -831,7 +831,8 @@ public:
     Operand = E;
   }
 
-  StringRef getUuidAsStringRef() const;
+  void setUuidStr(StringRef US) { UuidStr = US; }
+  StringRef getUuidStr() const { return UuidStr; }
 
   SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
   SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
index 438a376..6bd03b5 100644 (file)
@@ -54,10 +54,6 @@ QualType CXXUuidofExpr::getTypeOperand(ASTContext &Context) const {
       Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), Quals);
 }
 
-StringRef CXXUuidofExpr::getUuidAsStringRef() const {
-  return UA ? UA->getGuid() : "00000000-0000-0000-0000-000000000000";
-}
-
 // CXXScalarValueInitExpr
 SourceLocation CXXScalarValueInitExpr::getLocStart() const {
   return TypeInfo ? TypeInfo->getTypeLoc().getBeginLoc() : RParenLoc;
index 002c220..60ad168 100644 (file)
@@ -1186,7 +1186,7 @@ void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
 
     // This CXXUuidofExpr is mangled as-if it were actually a VarDecl from
     // const __s_GUID _GUID_{lower case UUID with underscores}
-    StringRef Uuid = UE->getUuidAsStringRef();
+    StringRef Uuid = UE->getUuidStr();
     std::string Name = "_GUID_" + Uuid.lower();
     std::replace(Name.begin(), Name.end(), '-', '_');
 
index 435d646..11f5bea 100644 (file)
@@ -1454,7 +1454,7 @@ ConstantAddress CodeGenModule::GetAddrOfUuidDescriptor(
     const CXXUuidofExpr* E) {
   // Sema has verified that IIDSource has a __declspec(uuid()), and that its
   // well-formed.
-  StringRef Uuid = E->getUuidAsStringRef();
+  StringRef Uuid = E->getUuidStr();
   std::string Name = "_GUID_" + Uuid.lower();
   std::replace(Name.begin(), Name.end(), '-', '_');
 
index 24c9844..73d87b0 100644 (file)
@@ -550,7 +550,7 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
                                 SourceLocation TypeidLoc,
                                 TypeSourceInfo *Operand,
                                 SourceLocation RParenLoc) {
-  const UuidAttr *UA = nullptr;
+  StringRef UuidStr;
   if (!Operand->getType()->isDependentType()) {
     llvm::SmallSetVector<const UuidAttr *, 1> UuidAttrs;
     getUuidAttrOfType(*this, Operand->getType(), UuidAttrs);
@@ -558,10 +558,10 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
       return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
     if (UuidAttrs.size() > 1)
       return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
-    UA = UuidAttrs.back();
+    UuidStr = UuidAttrs.back()->getGuid();
   }
 
-  return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UA,
+  return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UuidStr,
                                      SourceRange(TypeidLoc, RParenLoc));
 }
 
@@ -570,20 +570,22 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
                                 SourceLocation TypeidLoc,
                                 Expr *E,
                                 SourceLocation RParenLoc) {
-  const UuidAttr *UA = nullptr;
+  StringRef UuidStr;
   if (!E->getType()->isDependentType()) {
-    if (!E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
+    if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
+      UuidStr = "00000000-0000-0000-0000-000000000000";
+    } else {
       llvm::SmallSetVector<const UuidAttr *, 1> UuidAttrs;
       getUuidAttrOfType(*this, E->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));
-      UA = UuidAttrs.back();
+      UuidStr = UuidAttrs.back()->getGuid();
     }
   }
 
-  return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E, UA,
+  return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E, UuidStr,
                                      SourceRange(TypeidLoc, RParenLoc));
 }
 
index c2256eb..f8fb2b8 100644 (file)
@@ -1680,6 +1680,8 @@ void ASTStmtReader::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
 void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
   VisitExpr(E);
   E->setSourceRange(ReadSourceRange(Record, Idx));
+  std::string UuidStr = ReadString(Record, Idx);
+  E->setUuidStr(StringRef(UuidStr).copy(Reader.getContext()));
   if (E->isTypeOperand()) { // __uuidof(ComType)
     E->setTypeOperandSourceInfo(
         GetTypeSourceInfo(Record, Idx));
index 38cd892..3738c8e 100644 (file)
@@ -1701,6 +1701,7 @@ void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
 void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
   VisitExpr(E);
   Writer.AddSourceRange(E->getSourceRange(), Record);
+  Writer.AddString(E->getUuidStr(), Record);
   if (E->isTypeOperand()) {
     Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
     Code = serialization::EXPR_CXX_UUIDOF_TYPE;
diff --git a/clang/test/PCH/uuidof.cpp b/clang/test/PCH/uuidof.cpp
new file mode 100644 (file)
index 0000000..207a8da
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fms-extensions -x c++-header -emit-pch -o %t %s
+// RUN: %clang_cc1 -fms-extensions -include-pch %t -fsyntax-only %s -emit-llvm -o - | FileCheck %s
+
+#ifndef HEADER
+#define HEADER
+struct _GUID {};
+const _GUID &x = __uuidof(0);
+// CHECK-DAG: @_GUID_00000000_0000_0000_0000_000000000000
+#endif