]> granicus.if.org Git - clang/commitdiff
Make sure that ScopedDecls passed to DeclContext::addDecl are added into their lexica...
authorDouglas Gregor <dgregor@apple.com>
Fri, 9 Jan 2009 18:51:29 +0000 (18:51 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 9 Jan 2009 18:51:29 +0000 (18:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61998 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/AST/Decl.cpp
lib/AST/DeclBase.cpp
lib/Sema/SemaDecl.cpp

index 828c1be92555b8438d5ca461a4412c1de583503c..96bd8842b399e2b1420d99332684d458f58131af 100644 (file)
@@ -144,11 +144,15 @@ class ScopedDecl : public NamedDecl {
 protected:
   ScopedDecl(Kind DK, DeclContext *DC, SourceLocation L,
              DeclarationName N, ScopedDecl *PrevDecl = 0)
-    : NamedDecl(DK, L, N), NextDeclarator(PrevDecl),
+    : NamedDecl(DK, L, N), NextDeclarator(PrevDecl), 
       DeclCtx(reinterpret_cast<uintptr_t>(DC)) {}
 
   virtual ~ScopedDecl();
-  
+
+  /// setDeclContext - Set both the semantic and lexical DeclContext
+  /// to DC.
+  void setDeclContext(DeclContext *DC);
+
 public:
   const DeclContext *getDeclContext() const {
     if (isInSemaDC())
@@ -532,6 +536,12 @@ public:
 
   QualType getOriginalType() const;
   
+  /// setOwningFunction - Sets the function declaration that owns this
+  /// ParmVarDecl. Since ParmVarDecls are often created before the
+  /// FunctionDecls that own them, this routine is required to update
+  /// the DeclContext appropriately.
+  void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { 
     return (D->getKind() == ParmVar ||
index 8521b9b44ead6b33b17d50ead9c70d200bd940bb..f29417ed1320173b8654f0df6f3c58d098350588 100644 (file)
@@ -164,6 +164,13 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
 // ScopedDecl Implementation
 //===----------------------------------------------------------------------===//
 
+void ScopedDecl::setDeclContext(DeclContext *DC) {
+  if (isOutOfSemaDC())
+    delete getMultipleDC();
+  
+  DeclCtx = reinterpret_cast<uintptr_t>(DC);
+}
+
 void ScopedDecl::setLexicalDeclContext(DeclContext *DC) {
   if (DC == getLexicalDeclContext())
     return;
index f1ce3f3d0d99771bda0476248d9d5570f8c6ce13..d9765ac4b45e3edb79a06e90aad85bf69c233b07 100644 (file)
@@ -514,6 +514,7 @@ DeclContext *DeclContext::getNextContext() {
 }
 
 void DeclContext::addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup) {
+  assert(D->getLexicalDeclContext() == this && "Decl inserted into wrong lexical context");
   Decls.push_back(D);
   if (AllowLookup)
     D->getDeclContext()->insert(Context, D);
@@ -599,7 +600,6 @@ void DeclContext::insert(ASTContext &Context, ScopedDecl *D) {
   if (LookupPtr.getPointer())
     insertImpl(D);
 
-
   // If we are a transparent context, insert into our parent context,
   // too. This operation is recursive.
   if (isTransparentContext())
index d9436ebdc7f11499b66526bbc640e71cdb8d12da..ecf6de9d96f5ea93458c677566906ce10231c0d3 100644 (file)
@@ -441,7 +441,13 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
   
   
   // TUScope is the translation-unit scope to insert this function into.
+  // FIXME: This is hideous. We need to teach PushOnScopeChains to
+  // relate Scopes to DeclContexts, and probably eliminate CurContext
+  // entirely, but we're not there yet.
+  DeclContext *SavedContext = CurContext;
+  CurContext = Context.getTranslationUnitDecl();
   PushOnScopeChains(New, TUScope);
+  CurContext = SavedContext;
   return New;
 }
 
@@ -2705,6 +2711,8 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
   // Introduce our parameters into the function scope
   for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {
     ParmVarDecl *Param = FD->getParamDecl(p);
+    Param->setOwningFunction(FD);
+
     // If this has an identifier, add it to the scope stack.
     if (Param->getIdentifier())
       PushOnScopeChains(Param, FnBodyScope);