forked from OSchip/llvm-project
Revert "Revert "[-cxx-abi microsoft] Mangle local TagDecls appropriately""
This reverts commit r190895 which reverted r190892. llvm-svn: 190904
This commit is contained in:
parent
1b0256c379
commit
50ce835ecb
|
@ -2507,17 +2507,20 @@ private:
|
|||
// to be used for the (uncommon) case of out-of-line declarations.
|
||||
typedef QualifierInfo ExtInfo;
|
||||
|
||||
/// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name
|
||||
/// \brief If the (out-of-line) tag declaration name
|
||||
/// is qualified, it points to the qualifier info (nns and range);
|
||||
/// otherwise, if the tag declaration is anonymous and it is part of
|
||||
/// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
|
||||
/// otherwise, if the tag declaration is anonymous and it is used as a
|
||||
/// declaration specifier for variables, it points to the first VarDecl (used
|
||||
/// for mangling);
|
||||
/// otherwise, it is a null (TypedefNameDecl) pointer.
|
||||
llvm::PointerUnion<TypedefNameDecl*, ExtInfo*> TypedefNameDeclOrQualifier;
|
||||
llvm::PointerUnion<NamedDecl *, ExtInfo *> NamedDeclOrQualifier;
|
||||
|
||||
bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo*>(); }
|
||||
ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo*>(); }
|
||||
bool hasExtInfo() const { return NamedDeclOrQualifier.is<ExtInfo *>(); }
|
||||
ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get<ExtInfo *>(); }
|
||||
const ExtInfo *getExtInfo() const {
|
||||
return TypedefNameDeclOrQualifier.get<ExtInfo*>();
|
||||
return NamedDeclOrQualifier.get<ExtInfo *>();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -2527,7 +2530,7 @@ protected:
|
|||
IsCompleteDefinition(false), IsBeingDefined(false),
|
||||
IsEmbeddedInDeclarator(false), IsFreeStanding(false),
|
||||
IsCompleteDefinitionRequired(false),
|
||||
TypedefNameDeclOrQualifier((TypedefNameDecl *)0) {
|
||||
NamedDeclOrQualifier((NamedDecl *)0) {
|
||||
assert((DK != Enum || TK == TTK_Enum) &&
|
||||
"EnumDecl not matched with TTK_Enum");
|
||||
setPreviousDeclaration(PrevDecl);
|
||||
|
@ -2670,10 +2673,21 @@ public:
|
|||
return (getDeclName() || getTypedefNameForAnonDecl());
|
||||
}
|
||||
|
||||
TypedefNameDecl *getTypedefNameForAnonDecl() const {
|
||||
return hasExtInfo() ? 0 :
|
||||
TypedefNameDeclOrQualifier.get<TypedefNameDecl*>();
|
||||
bool hasDeclaratorForAnonDecl() const {
|
||||
return dyn_cast_or_null<DeclaratorDecl>(
|
||||
NamedDeclOrQualifier.get<NamedDecl *>());
|
||||
}
|
||||
DeclaratorDecl *getDeclaratorForAnonDecl() const {
|
||||
return hasExtInfo() ? 0 : dyn_cast_or_null<DeclaratorDecl>(
|
||||
NamedDeclOrQualifier.get<NamedDecl *>());
|
||||
}
|
||||
|
||||
TypedefNameDecl *getTypedefNameForAnonDecl() const {
|
||||
return hasExtInfo() ? 0 : dyn_cast_or_null<TypedefNameDecl>(
|
||||
NamedDeclOrQualifier.get<NamedDecl *>());
|
||||
}
|
||||
|
||||
void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; }
|
||||
|
||||
void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
|
||||
|
||||
|
|
|
@ -3084,7 +3084,7 @@ TagDecl* TagDecl::getCanonicalDecl() {
|
|||
}
|
||||
|
||||
void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
|
||||
TypedefNameDeclOrQualifier = TDD;
|
||||
NamedDeclOrQualifier = TDD;
|
||||
if (TypeForDecl)
|
||||
assert(TypeForDecl->isLinkageValid());
|
||||
assert(isLinkageValid());
|
||||
|
@ -3141,7 +3141,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
|
|||
if (QualifierLoc) {
|
||||
// Make sure the extended qualifier info is allocated.
|
||||
if (!hasExtInfo())
|
||||
TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo;
|
||||
NamedDeclOrQualifier = new (getASTContext()) ExtInfo;
|
||||
// Set qualifier info.
|
||||
getExtInfo()->QualifierLoc = QualifierLoc;
|
||||
} else {
|
||||
|
@ -3149,7 +3149,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
|
|||
if (hasExtInfo()) {
|
||||
if (getExtInfo()->NumTemplParamLists == 0) {
|
||||
getASTContext().Deallocate(getExtInfo());
|
||||
TypedefNameDeclOrQualifier = (TypedefNameDecl*) 0;
|
||||
NamedDeclOrQualifier = (TypedefNameDecl*) 0;
|
||||
}
|
||||
else
|
||||
getExtInfo()->QualifierLoc = QualifierLoc;
|
||||
|
@ -3164,7 +3164,7 @@ void TagDecl::setTemplateParameterListsInfo(ASTContext &Context,
|
|||
// Make sure the extended decl info is allocated.
|
||||
if (!hasExtInfo())
|
||||
// Allocate external info struct.
|
||||
TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo;
|
||||
NamedDeclOrQualifier = new (getASTContext()) ExtInfo;
|
||||
// Set the template parameter lists info.
|
||||
getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
|
||||
}
|
||||
|
|
|
@ -563,9 +563,15 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
|
|||
break;
|
||||
}
|
||||
|
||||
// When VC encounters an anonymous type with no tag and no typedef,
|
||||
// it literally emits '<unnamed-tag>@'.
|
||||
Out << "<unnamed-tag>@";
|
||||
if (TD->hasDeclaratorForAnonDecl())
|
||||
// Anonymous types with no tag or typedef get the name of their
|
||||
// declarator mangled in.
|
||||
Out << "<unnamed-type-" << TD->getDeclaratorForAnonDecl()->getName()
|
||||
<< ">@";
|
||||
else
|
||||
// Anonymous types with no tag, no typedef, or declarator get
|
||||
// '<unnamed-tag>@'.
|
||||
Out << "<unnamed-tag>@";
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -8814,13 +8814,21 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
|
|||
if (DS.isTypeSpecOwned())
|
||||
Decls.push_back(DS.getRepAsDecl());
|
||||
|
||||
DeclaratorDecl *FirstDeclaratorInGroup = 0;
|
||||
for (unsigned i = 0, e = Group.size(); i != e; ++i)
|
||||
if (Decl *D = Group[i])
|
||||
if (Decl *D = Group[i]) {
|
||||
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
|
||||
if (!FirstDeclaratorInGroup)
|
||||
FirstDeclaratorInGroup = DD;
|
||||
Decls.push_back(D);
|
||||
}
|
||||
|
||||
if (DeclSpec::isDeclRep(DS.getTypeSpecType())) {
|
||||
if (const TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl()))
|
||||
if (TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) {
|
||||
HandleTagNumbering(*this, Tag);
|
||||
if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl())
|
||||
Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup);
|
||||
}
|
||||
}
|
||||
|
||||
return BuildDeclaratorGroup(Decls, DS.containsPlaceholderType());
|
||||
|
|
|
@ -3356,6 +3356,19 @@ void Sema::BuildVariableInstantiation(
|
|||
NewVar->setReferenced(OldVar->isReferenced());
|
||||
}
|
||||
|
||||
// See if the old variable had a type-specifier that defined an anonymous tag.
|
||||
// If it did, mark the new variable as being the declarator for the new
|
||||
// anonymous tag.
|
||||
if (const TagType *OldTagType = OldVar->getType()->getAs<TagType>()) {
|
||||
TagDecl *OldTag = OldTagType->getDecl();
|
||||
if (OldTag->getDeclaratorForAnonDecl() == OldVar) {
|
||||
TagDecl *NewTag = NewVar->getType()->castAs<TagType>()->getDecl();
|
||||
assert(!NewTag->hasNameForLinkage() &&
|
||||
!NewTag->hasDeclaratorForAnonDecl());
|
||||
NewTag->setDeclaratorForAnonDecl(NewVar);
|
||||
}
|
||||
}
|
||||
|
||||
InstantiateAttrs(TemplateArgs, OldVar, NewVar, LateAttrs, StartingScope);
|
||||
|
||||
if (NewVar->hasAttrs())
|
||||
|
|
|
@ -464,9 +464,9 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) {
|
|||
if (Record[Idx++]) { // hasExtInfo
|
||||
TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo();
|
||||
ReadQualifierInfo(*Info, Record, Idx);
|
||||
TD->TypedefNameDeclOrQualifier = Info;
|
||||
TD->NamedDeclOrQualifier = Info;
|
||||
} else
|
||||
TD->setTypedefNameForAnonDecl(ReadDeclAs<TypedefNameDecl>(Record, Idx));
|
||||
TD->NamedDeclOrQualifier = ReadDeclAs<NamedDecl>(Record, Idx);
|
||||
|
||||
mergeRedeclarable(TD, Redecl);
|
||||
return Redecl;
|
||||
|
|
|
@ -229,6 +229,8 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
|
|||
Record.push_back(D->hasExtInfo());
|
||||
if (D->hasExtInfo())
|
||||
Writer.AddQualifierInfo(*D->getExtInfo(), Record);
|
||||
else if (D->hasDeclaratorForAnonDecl())
|
||||
Writer.AddDeclRef(D->getDeclaratorForAnonDecl(), Record);
|
||||
else
|
||||
Writer.AddDeclRef(D->getTypedefNameForAnonDecl(), Record);
|
||||
}
|
||||
|
|
|
@ -275,3 +275,32 @@ int wWinMain() { return 0; }
|
|||
int DllMain() { return 0; }
|
||||
// CHECK-DAG: @DllMain
|
||||
// X64-DAG: @DllMain
|
||||
|
||||
inline int inline_function_with_local_type() {
|
||||
static struct {
|
||||
int a_field;
|
||||
} static_variable_in_inline_function = { 20 }, second_static = { 40 };
|
||||
// CHECK: @"\01?static_variable_in_inline_function@?1??inline_function_with_local_type@@YAHXZ@4U<unnamed-type-static_variable_in_inline_function>@?1??1@YAHXZ@A"
|
||||
|
||||
return static_variable_in_inline_function.a_field + second_static.a_field;
|
||||
}
|
||||
|
||||
int call_inline_function_with_local_type() {
|
||||
return inline_function_with_local_type();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int templated_inline_function_with_local_type() {
|
||||
static struct {
|
||||
int a_field;
|
||||
} static_variable_in_templated_inline_function = { 20 },
|
||||
second_static = { 40 };
|
||||
// CHECK: @"\01?static_variable_in_templated_inline_function@?1???$templated_inline_function_with_local_type@H@@YAHXZ@4U<unnamed-type-static_variable_in_templated_inline_function>@?1???$templated_inline_function_with_local_type@H@@YAHXZ@A"
|
||||
|
||||
return static_variable_in_templated_inline_function.a_field +
|
||||
second_static.a_field;
|
||||
}
|
||||
|
||||
int call_templated_inline_function_with_local_type() {
|
||||
return templated_inline_function_with_local_type<int>();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue