aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/DeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2013-02-09 01:35:03 +0000
committerDouglas Gregor <dgregor@apple.com>2013-02-09 01:35:03 +0000
commit6bd992946bda92193fadce7e4890d4465d2702f4 (patch)
tree3f4481d4238755cbddf2d8c767971a13e90458c7 /lib/AST/DeclCXX.cpp
parentf07e815823e03c046bbc186ec2b41d656e9cac7f (diff)
Ensure that type definitions present in just-loaded modules are
visible. The basic problem here is that a given translation unit can use forward declarations to form pointers to a given type, say, class X; X *x; and then import a module that includes a definition of X: import XDef; We will then fail when attempting to access a member of X, e.g., x->method() because the AST reader did not know to look for a default of a class named X within the new module. This implementation is a bit of a C-centric hack, because the only definitions that can have this property are enums, structs, unions, Objective-C classes, and Objective-C protocols, and all of those are either visible at the top-level or can't be defined later. Hence, we can use the out-of-date-ness of the name and the identifier-update mechanism to force the update. In C++, we will not be so lucky, and will need a more advanced solution, because the definitions could be in namespaces defined in two different modules, e.g., // module 1 namespace N { struct X; } // module 2 namespace N { struct X { /* ... */ }; } One possible implementation here is for C++ to extend the information associated with each identifier table to include the declaration IDs of any definitions associated with that name, regardless of context. We would have to eagerly load those definitions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174794 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r--lib/AST/DeclCXX.cpp9
1 files changed, 7 insertions, 2 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 90a2b4ab46..4dd3694bc4 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -87,6 +87,7 @@ CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
bool DelayTypeCreation) {
CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, StartLoc, IdLoc,
Id, PrevDecl);
+ R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
// FIXME: DelayTypeCreation seems like such a hack
if (!DelayTypeCreation)
@@ -101,6 +102,7 @@ CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
0, 0);
R->IsBeingDefined = true;
R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, Dependent);
+ R->MayHaveOutOfDateDef = false;
C.getTypeDeclType(R, /*PrevDecl=*/0);
return R;
}
@@ -108,8 +110,11 @@ CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
CXXRecordDecl *
CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXRecordDecl));
- return new (Mem) CXXRecordDecl(CXXRecord, TTK_Struct, 0, SourceLocation(),
- SourceLocation(), 0, 0);
+ CXXRecordDecl *R = new (Mem) CXXRecordDecl(CXXRecord, TTK_Struct, 0,
+ SourceLocation(), SourceLocation(),
+ 0, 0);
+ R->MayHaveOutOfDateDef = false;
+ return R;
}
void