]> granicus.if.org Git - clang/commitdiff
Serialize and deserialize mangling numbers.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 21 Mar 2014 01:48:23 +0000 (01:48 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 21 Mar 2014 01:48:23 +0000 (01:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204423 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Serialization/ASTWriter.h
lib/Serialization/ASTCommon.h
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriter.cpp
test/PCH/cxx-mangling.cpp [new file with mode: 0644]

index 68c92930e9b72fc5b740266aa1833b3fca73444c..91afeabfa1cdb16e302e3d1912b6457b2388a1b1 100644 (file)
@@ -291,6 +291,7 @@ private:
       const Decl *Dcl;
       void *Type;
       unsigned Loc;
+      unsigned Val;
     };
 
   public:
@@ -300,6 +301,8 @@ private:
         : Kind(Kind), Type(Type.getAsOpaquePtr()) {}
     DeclUpdate(unsigned Kind, SourceLocation Loc)
         : Kind(Kind), Loc(Loc.getRawEncoding()) {}
+    DeclUpdate(unsigned Kind, unsigned Val)
+        : Kind(Kind), Val(Val) {}
 
     unsigned getKind() const { return Kind; }
     const Decl *getDecl() const { return Dcl; }
@@ -307,6 +310,7 @@ private:
     SourceLocation getLoc() const {
       return SourceLocation::getFromRawEncoding(Loc);
     }
+    unsigned getNumber() const { return Val; }
   };
 
   typedef SmallVector<DeclUpdate, 1> UpdateRecord;
index b6f54a472eee257aa89c62a042fdc3815caa2f96..9f4d7a9acddeb5464c5b8384003aa5655f4952c2 100644 (file)
@@ -28,7 +28,9 @@ enum DeclUpdateKind {
   UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
   UPD_CXX_RESOLVED_EXCEPTION_SPEC,
   UPD_CXX_DEDUCED_RETURN_TYPE,
-  UPD_DECL_MARKED_USED
+  UPD_DECL_MARKED_USED,
+  UPD_MANGLING_NUMBER,
+  UPD_STATIC_LOCAL_NUMBER
 };
 
 TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
index 53c26e94e1ffee66b2e1ee2a46105c72cd4bd409..c186ba00ee57741db71954c88992d8ac0c0b6a5e 100644 (file)
@@ -2968,6 +2968,14 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
       D->Used = true;
       break;
     }
+
+    case UPD_MANGLING_NUMBER:
+      Reader.Context.setManglingNumber(cast<NamedDecl>(D), Record[Idx++]);
+      break;
+
+    case UPD_STATIC_LOCAL_NUMBER:
+      Reader.Context.setStaticLocalNumber(cast<VarDecl>(D), Record[Idx++]);
+      break;
     }
   }
 }
index 55dd375dc1ffad4f733bf743d1fc831caea17e9c..1399ce2434c100c7b3fe38b5aab1976c38079fe3 100644 (file)
@@ -4085,6 +4085,17 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
       Record.push_back({UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, NS});
   }
 
+  // Add update records for all mangling numbers and static local numbers.
+  // These aren't really update records, but this is a convenient way of
+  // tagging this rare extra data onto the declarations.
+  for (const auto &Number : Context.MangleNumbers)
+    if (!Number.first->isFromASTFile())
+      DeclUpdates[Number.first].push_back({UPD_MANGLING_NUMBER, Number.second});
+  for (const auto &Number : Context.StaticLocalNumbers)
+    if (!Number.first->isFromASTFile())
+      DeclUpdates[Number.first].push_back({UPD_STATIC_LOCAL_NUMBER,
+                                           Number.second});
+
   // Make sure visible decls, added to DeclContexts previously loaded from
   // an AST file, are registered for serialization.
   for (SmallVectorImpl<const Decl *>::iterator
@@ -4187,13 +4198,12 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
   } while (!DeclUpdates.empty());
   Stream.ExitBlock();
 
-  if (!DeclUpdatesOffsetsRecord.empty())
-    Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
-
   DoneWritingDeclsAndTypes = true;
 
   // These things can only be done once we've written out decls and types.
   WriteTypeDeclOffsets();
+  if (!DeclUpdatesOffsetsRecord.empty())
+    Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
   WriteCXXBaseSpecifiersOffsets();
   WriteFileDeclIDsMap();
   WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
@@ -4372,6 +4382,11 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
 
       case UPD_DECL_MARKED_USED:
         break;
+
+      case UPD_MANGLING_NUMBER:
+      case UPD_STATIC_LOCAL_NUMBER:
+        Record.push_back(Update.getNumber());
+        break;
       }
     }
 
diff --git a/test/PCH/cxx-mangling.cpp b/test/PCH/cxx-mangling.cpp
new file mode 100644 (file)
index 0000000..d086f26
--- /dev/null
@@ -0,0 +1,28 @@
+// Test without PCH.
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include %s %s -emit-llvm -o - | FileCheck %s
+//
+// Test with PCH.
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -x c++-header %s -emit-pch -o %t
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - | FileCheck %s
+
+#ifndef HEADER
+#define HEADER
+
+struct A {
+  struct { int a; } a;
+  struct { int b; } b;
+};
+
+#else
+
+template<typename T> void f(T) {}
+
+// CHECK-LABEL: define void @_Z1g1A(
+void g(A a) {
+  // CHECK: call void @_Z1fIN1AUt0_EEvT_(
+  f(a.b);
+  // CHECK: call void @_Z1fIN1AUt_EEvT_(
+  f(a.a);
+}
+
+#endif