[cfe-commits] r80657 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/TreeTransform.h test/SemaTemplate/instantiate-anonymous-union.cpp
Anders Carlsson
andersca at mac.com
Mon Aug 31 21:26:59 PDT 2009
Author: andersca
Date: Mon Aug 31 23:26:58 2009
New Revision: 80657
URL: http://llvm.org/viewvc/llvm-project?rev=80657&view=rev
Log:
Don't assert when instantiating member references to fields in anonymous structs.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=80657&r1=80656&r2=80657&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Aug 31 23:26:58 2009
@@ -196,6 +196,8 @@
llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>
InstantiatedFromUnresolvedUsingDecl;
+ llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
+
TranslationUnitDecl *TUDecl;
/// SourceMgr - The associated SourceManager object.
@@ -267,12 +269,23 @@
/// the static data member template \p Tmpl of a class template.
void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl);
+ /// \brief If this using decl is instantiated from an unresolved using decl,
+ /// return it.
UnresolvedUsingDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
- void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD,
- UnresolvedUsingDecl *UUD);
+
+ /// \brief Note that the using decl \p Inst is an instantiation of
+ /// the unresolved using decl \p Tmpl of a class template.
+ void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst,
+ UnresolvedUsingDecl *Tmpl);
+
+
+ FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
+
+ void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
+
const char *getCommentForDecl(const Decl *D);
// Builtin Types.
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=80657&r1=80656&r2=80657&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Aug 31 23:26:58 2009
@@ -260,6 +260,25 @@
InstantiatedFromUnresolvedUsingDecl[UD] = UUD;
}
+FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {
+ llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos
+ = InstantiatedFromUnnamedFieldDecl.find(Field);
+ if (Pos == InstantiatedFromUnnamedFieldDecl.end())
+ return 0;
+
+ return Pos->second;
+}
+
+void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,
+ FieldDecl *Tmpl) {
+ assert(!Inst->getDeclName() && "Instantiated field decl is not unnamed");
+ assert(!Tmpl->getDeclName() && "Template field decl is not unnamed");
+ assert(!InstantiatedFromUnnamedFieldDecl[Inst] &&
+ "Already noted what unnamed field was instantiated from");
+
+ InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl;
+}
+
namespace {
class BeforeInTranslationUnit
: std::binary_function<SourceRange, SourceRange, bool> {
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80657&r1=80656&r2=80657&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Aug 31 23:26:58 2009
@@ -245,6 +245,11 @@
if (Invalid)
Field->setInvalidDecl();
+ if (!Field->getDeclName()) {
+ // Keep track of where this decl came from.
+ SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D);
+ }
+
Owner->addDecl(Field);
}
@@ -441,6 +446,8 @@
if (Decl::FriendObjectKind FOK = D->getFriendObjectKind())
Record->setObjectOfFriendDecl(FOK == Decl::FOK_Declared);
+ Record->setAnonymousStructOrUnion(D->isAnonymousStructOrUnion());
+
Owner->addDecl(Record);
return Record;
}
@@ -1274,8 +1281,14 @@
if (ClassTemplateDecl *Temp = dyn_cast<ClassTemplateDecl>(Other))
return isInstantiationOf(cast<ClassTemplateDecl>(D), Temp);
- // FIXME: How can we find instantiations of anonymous unions?
-
+ if (FieldDecl *Field = dyn_cast<FieldDecl>(Other)) {
+ if (!Field->getDeclName()) {
+ // This is an unnamed field.
+ return Ctx.getInstantiatedFromUnnamedFieldDecl(Field) ==
+ cast<FieldDecl>(D);
+ }
+ }
+
return D->getDeclName() && isa<NamedDecl>(Other) &&
D->getDeclName() == cast<NamedDecl>(Other)->getDeclName();
}
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=80657&r1=80656&r2=80657&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Aug 31 23:26:58 2009
@@ -840,6 +840,17 @@
SourceRange QualifierRange,
SourceLocation MemberLoc,
NamedDecl *Member) {
+ if (!Member->getDeclName()) {
+ // We have a reference to an unnamed field.
+ assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
+
+ MemberExpr *ME =
+ new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
+ Member, MemberLoc,
+ cast<FieldDecl>(Member)->getType());
+ return getSema().Owned(ME);
+ }
+
CXXScopeSpec SS;
if (Qualifier) {
SS.setRange(QualifierRange);
Modified: cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp?rev=80657&r1=80656&r2=80657&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp Mon Aug 31 23:26:58 2009
@@ -6,3 +6,16 @@
A<int> a0;
+template <typename T> struct B {
+ union {
+ int a;
+ void* b;
+ };
+
+ void f() {
+ a = 10;
+ b = 0;
+ }
+};
+
+B<int> b0;
More information about the cfe-commits
mailing list