[cfe-commits] r83095 - in /cfe/trunk: include/clang/Index/ASTLocation.h lib/Analysis/CallGraph.cpp lib/Index/ASTLocation.cpp lib/Index/Analyzer.cpp lib/Index/ResolveLocation.cpp test/Index/resolve-loc.c tools/CIndex/CIndex.cpp tools/index-test/index-test.cpp

Argiris Kirtzidis akyrtzi at gmail.com
Tue Sep 29 12:44:27 PDT 2009


Author: akirtzidis
Date: Tue Sep 29 14:44:27 2009
New Revision: 83095

URL: http://llvm.org/viewvc/llvm-project?rev=83095&view=rev
Log:
Modify ASTLocation and apart from being a Decl or Stmt, allow it to also be:

-A NamedDecl reference
-A TypeLoc

Modified:
    cfe/trunk/include/clang/Index/ASTLocation.h
    cfe/trunk/lib/Analysis/CallGraph.cpp
    cfe/trunk/lib/Index/ASTLocation.cpp
    cfe/trunk/lib/Index/Analyzer.cpp
    cfe/trunk/lib/Index/ResolveLocation.cpp
    cfe/trunk/test/Index/resolve-loc.c
    cfe/trunk/tools/CIndex/CIndex.cpp
    cfe/trunk/tools/index-test/index-test.cpp

Modified: cfe/trunk/include/clang/Index/ASTLocation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Index/ASTLocation.h?rev=83095&r1=83094&r2=83095&view=diff

==============================================================================
--- cfe/trunk/include/clang/Index/ASTLocation.h (original)
+++ cfe/trunk/include/clang/Index/ASTLocation.h Tue Sep 29 14:44:27 2009
@@ -14,7 +14,8 @@
 #ifndef LLVM_CLANG_INDEX_ASTLOCATION_H
 #define LLVM_CLANG_INDEX_ASTLOCATION_H
 
-#include <cassert>
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/PointerIntPair.h"
 
 namespace llvm {
   class raw_ostream;
@@ -23,7 +24,7 @@
 namespace clang {
   class Decl;
   class Stmt;
-  class SourceRange;
+  class NamedDecl;
 
 namespace idx {
   class TranslationUnit;
@@ -37,26 +38,105 @@
 /// like the declaration context, ASTContext, etc.
 ///
 class ASTLocation {
-  const Decl *D;
-  const Stmt *Stm;
+public:
+  enum NodeKind {
+    N_Decl, N_NamedRef, N_Stmt, N_Type
+  };
+
+  struct NamedRef {
+    NamedDecl *ND;
+    SourceLocation Loc;
+    
+    NamedRef() : ND(0) { }
+    NamedRef(NamedDecl *nd, SourceLocation loc) : ND(nd), Loc(loc) { }
+  };
+
+private:
+  llvm::PointerIntPair<Decl *, 2, NodeKind> ParentDecl;
+
+  union {
+    Decl *D;
+    Stmt *Stm;
+    struct {
+      NamedDecl *ND;
+      unsigned RawLoc;
+    } NDRef;
+    struct {
+      void *TyPtr;
+      void *Data;
+    } Ty;
+  };
 
 public:
-  ASTLocation() : D(0), Stm(0) {}
+  ASTLocation() { }
+
+  explicit ASTLocation(const Decl *d)
+    : ParentDecl(const_cast<Decl*>(d), N_Decl), D(const_cast<Decl*>(d)) { }
 
-  explicit ASTLocation(const Decl *d, const Stmt *stm = 0) : D(d), Stm(stm) {
-    assert((Stm == 0 || isImmediateParent(D, Stm)) &&
-           "The Decl is not the immediate parent of the Stmt.");
+  ASTLocation(const Decl *parentDecl, const Stmt *stm)
+    : ParentDecl(const_cast<Decl*>(parentDecl), N_Stmt),
+      Stm(const_cast<Stmt*>(stm)) {
+    if (!stm) ParentDecl.setPointer(0);
   }
 
-  const Decl *getDecl() const { return D; }
-  const Stmt *getStmt() const { return Stm; }
-  Decl *getDecl() { return const_cast<Decl*>(D); }
-  Stmt *getStmt() { return const_cast<Stmt*>(Stm); }
+  ASTLocation(const Decl *parentDecl, NamedDecl *ndRef, SourceLocation loc)
+    : ParentDecl(const_cast<Decl*>(parentDecl), N_NamedRef) {
+    if (ndRef) {
+      NDRef.ND = ndRef;
+      NDRef.RawLoc = loc.getRawEncoding();
+    } else
+      ParentDecl.setPointer(0);
+  }
+
+  ASTLocation(const Decl *parentDecl, TypeLoc tyLoc)
+    : ParentDecl(const_cast<Decl*>(parentDecl), N_Type) {
+    if (tyLoc) {
+      Ty.TyPtr = tyLoc.getSourceType().getAsOpaquePtr();
+      Ty.Data = tyLoc.getOpaqueData();
+    } else
+      ParentDecl.setPointer(0);
+  }
 
-  bool isValid() const { return D != 0; }
+  bool isValid() const { return ParentDecl.getPointer() != 0; }
   bool isInvalid() const { return !isValid(); }
-  bool isDecl() const { return isValid() && Stm == 0; }
-  bool isStmt() const { return isValid() && Stm != 0; }
+  
+  NodeKind getKind() const {
+    assert(isValid());
+    return (NodeKind)ParentDecl.getInt();
+  }
+  
+  Decl *getParentDecl() const { return ParentDecl.getPointer(); }
+  
+  Decl *AsDecl() const {
+    assert(getKind() == N_Decl);
+    return D;
+  }
+  Stmt *AsStmt() const {
+    assert(getKind() == N_Stmt);
+    return Stm;
+  }
+  NamedRef AsNamedRef() const {
+    assert(getKind() == N_NamedRef);
+    return NamedRef(NDRef.ND, SourceLocation::getFromRawEncoding(NDRef.RawLoc));
+  }
+  TypeLoc AsTypeLoc() const {
+    assert(getKind() == N_Type);
+    return TypeLoc(QualType::getFromOpaquePtr(Ty.TyPtr), Ty.Data);
+  }
+
+  Decl *dyn_AsDecl() const { return getKind() == N_Decl ? D : 0; }
+  Stmt *dyn_AsStmt() const { return getKind() == N_Stmt ? Stm : 0; }
+  NamedRef dyn_AsNamedRef() const {
+    return getKind() == N_Type ? AsNamedRef() : NamedRef();
+  }
+  TypeLoc dyn_AsTypeLoc() const {
+    return getKind() == N_Type ? AsTypeLoc() : TypeLoc();
+  }
+  
+  bool isDecl() const { return isValid() && getKind() == N_Decl; }
+  bool isStmt() const { return isValid() && getKind() == N_Stmt; }
+  bool isNamedRef() const { return isValid() && getKind() == N_NamedRef; }
+  bool isType() const { return isValid() && getKind() == N_Type; }
 
   /// \brief Returns the declaration that this ASTLocation references.
   ///
@@ -70,17 +150,6 @@
 
   SourceRange getSourceRange() const;
 
-  /// \brief Checks that D is the immediate Decl parent of Node.
-  static bool isImmediateParent(const Decl *D, const Stmt *Node);
-  static const Decl *FindImmediateParent(const Decl *D, const Stmt *Node);
-
-  friend bool operator==(const ASTLocation &L, const ASTLocation &R) {
-    return L.D == R.D && L.Stm == R.Stm;
-  }
-  friend bool operator!=(const ASTLocation &L, const ASTLocation &R) {
-    return !(L == R);
-  }
-
   void print(llvm::raw_ostream &OS) const;
 };
 

Modified: cfe/trunk/lib/Analysis/CallGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CallGraph.cpp?rev=83095&r1=83094&r2=83095&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CallGraph.cpp (original)
+++ cfe/trunk/lib/Analysis/CallGraph.cpp Tue Sep 29 14:44:27 2009
@@ -51,10 +51,7 @@
   if (FunctionDecl *CalleeDecl = CE->getDirectCallee()) {
     Entity Ent = Entity::get(CalleeDecl, G.getProgram());
     CallGraphNode *CalleeNode = G.getOrInsertFunction(Ent);
-
-    const Decl *Parent = ASTLocation::FindImmediateParent(FD, CE);
-
-    CallerNode->addCallee(ASTLocation(Parent, CE), CalleeNode);
+    CallerNode->addCallee(ASTLocation(FD, CE), CalleeNode);
   }
 }
 

Modified: cfe/trunk/lib/Index/ASTLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/ASTLocation.cpp?rev=83095&r1=83094&r2=83095&view=diff

==============================================================================
--- cfe/trunk/lib/Index/ASTLocation.cpp (original)
+++ cfe/trunk/lib/Index/ASTLocation.cpp Tue Sep 29 14:44:27 2009
@@ -39,94 +39,40 @@
 Decl *ASTLocation::getReferencedDecl() {
   if (isInvalid())
     return 0;
-  if (isDecl())
-    return getDecl();
 
-  assert(getStmt());
-  return getDeclFromExpr(getStmt());
-}
-
-
-static bool isContainedInStatement(const Stmt *Node, const Stmt *Parent) {
-  assert(Node && Parent && "Passed null Node or Parent");
-
-  if (Node == Parent)
-    return true;
-
-  for (Stmt::const_child_iterator
-         I = Parent->child_begin(), E = Parent->child_end(); I != E; ++I) {
-    if (*I)
-      if (isContainedInStatement(Node, *I))
-        return true;
-  }
-
-  return false;
-}
-
-const Decl *ASTLocation::FindImmediateParent(const Decl *D, const Stmt *Node) {
-  assert(D && Node && "Passed null Decl or null Stmt");
-
-  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
-    const Expr *Init = VD->getInit();
-    if (Init == 0)
-      return 0;
-    return isContainedInStatement(Node, Init) ? D : 0;
-  }
-
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    if (!FD->isThisDeclarationADefinition())
-      return 0;
-
-    for (DeclContext::decl_iterator
-           I = FD->decls_begin(), E = FD->decls_end(); I != E; ++I) {
-      const Decl *Child = FindImmediateParent(*I, Node);
-      if (Child)
-        return Child;
-    }
-
-    assert(FD->getBody() && "If not definition we should have exited already");
-    return isContainedInStatement(Node, FD->getBody()) ? D : 0;
-  }
-
-  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
-    if (!MD->getBody())
-      return 0;
-
-    for (DeclContext::decl_iterator
-           I = MD->decls_begin(), E = MD->decls_end(); I != E; ++I) {
-      const Decl *Child = FindImmediateParent(*I, Node);
-      if (Child)
-        return Child;
-    }
-
-    assert(MD->getBody() && "If not definition we should have exited already");
-    return isContainedInStatement(Node, MD->getBody()) ? D : 0;
-  }
-
-  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
-    for (DeclContext::decl_iterator
-           I = BD->decls_begin(), E = BD->decls_end(); I != E; ++I) {
-      const Decl *Child = FindImmediateParent(*I, Node);
-      if (Child)
-        return Child;
-    }
-
-    assert(BD->getBody() && "BlockDecl without body ?");
-    return isContainedInStatement(Node, BD->getBody()) ? D : 0;
+  switch (getKind()) {
+  default: assert(0 && "Invalid Kind");
+  case N_Type:
+    return 0;
+  case N_Decl:
+    return D;
+  case N_NamedRef:
+    return NDRef.ND;
+  case N_Stmt:
+    return getDeclFromExpr(Stm);
   }
-
+  
   return 0;
 }
 
-bool ASTLocation::isImmediateParent(const Decl *D, const Stmt *Node) {
-  assert(D && Node && "Passed null Decl or null Stmt");
-  return D == FindImmediateParent(D, Node);
-}
-
 SourceRange ASTLocation::getSourceRange() const {
   if (isInvalid())
     return SourceRange();
-  return isDecl() ? getDecl()->getSourceRange() : getStmt()->getSourceRange();
+
+  switch (getKind()) {
+  default: assert(0 && "Invalid Kind");
+    return SourceRange();
+  case N_Decl:
+    return D->getSourceRange();
+  case N_Stmt:
+    return Stm->getSourceRange();
+  case N_NamedRef:
+    return SourceRange(AsNamedRef().Loc, AsNamedRef().Loc);
+  case N_Type:
+    return AsTypeLoc().getSourceRange();
+  }
+  
+  return SourceRange();
 }
 
 void ASTLocation::print(llvm::raw_ostream &OS) const {
@@ -134,21 +80,36 @@
     OS << "<< Invalid ASTLocation >>\n";
     return;
   }
+  
+  ASTContext &Ctx = getParentDecl()->getASTContext();
 
-  OS << "[Decl: " << getDecl()->getDeclKindName() << " ";
-  if (const NamedDecl *ND = dyn_cast<NamedDecl>(getDecl()))
-    OS << ND->getNameAsString();
-
-  if (getStmt()) {
-    ASTContext &Ctx = getDecl()->getASTContext();
-    OS << " | Stmt: " << getStmt()->getStmtClassName() << " ";
-    getStmt()->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
+  switch (getKind()) {
+  case N_Decl:
+    OS << "[Decl: " << AsDecl()->getDeclKindName() << " ";
+    if (const NamedDecl *ND = dyn_cast<NamedDecl>(AsDecl()))
+      OS << ND->getNameAsString();
+    break;
+
+  case N_Stmt:
+    OS << "[Stmt: " << AsStmt()->getStmtClassName() << " ";
+    AsStmt()->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
+    break;
+    
+  case N_NamedRef:
+    OS << "[NamedRef: " << AsNamedRef().ND->getDeclKindName() << " ";
+    OS << AsNamedRef().ND->getNameAsString();
+    break;
+    
+  case N_Type: {
+    QualType T = AsTypeLoc().getSourceType();
+    OS << "[Type: " << T->getTypeClassName() << " " << T.getAsString();
+  }
   }
 
   OS << "] <";
 
   SourceRange Range = getSourceRange();
-  SourceManager &SourceMgr = getDecl()->getASTContext().getSourceManager();
+  SourceManager &SourceMgr = Ctx.getSourceManager();
   Range.getBegin().print(OS, SourceMgr);
   OS << ", ";
   Range.getEnd().print(OS, SourceMgr);

Modified: cfe/trunk/lib/Index/Analyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/Analyzer.cpp?rev=83095&r1=83094&r2=83095&view=diff

==============================================================================
--- cfe/trunk/lib/Index/Analyzer.cpp (original)
+++ cfe/trunk/lib/Index/Analyzer.cpp Tue Sep 29 14:44:27 2009
@@ -144,16 +144,15 @@
   /// It returns true "eagerly", meaning it will return false only if it can
   /// "prove" statically that the interface cannot accept this message.
   bool ValidReference(ASTLocation ASTLoc, ObjCInterfaceDecl *IFace) {
-    assert(ASTLoc.isValid());
     assert(ASTLoc.isStmt());
 
     // FIXME: Finding @selector references should be through another Analyzer
     // method, like FindSelectors.
-    if (isa<ObjCSelectorExpr>(ASTLoc.getStmt()))
+    if (isa<ObjCSelectorExpr>(ASTLoc.AsStmt()))
       return false;
 
     ObjCInterfaceDecl *MsgD = 0;
-    ObjCMessageExpr *Msg = cast<ObjCMessageExpr>(ASTLoc.getStmt());
+    ObjCMessageExpr *Msg = cast<ObjCMessageExpr>(ASTLoc.AsStmt());
 
     if (Msg->getReceiver()) {
       const ObjCObjectPointerType *OPT =

Modified: cfe/trunk/lib/Index/ResolveLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/ResolveLocation.cpp?rev=83095&r1=83094&r2=83095&view=diff

==============================================================================
--- cfe/trunk/lib/Index/ResolveLocation.cpp (original)
+++ cfe/trunk/lib/Index/ResolveLocation.cpp Tue Sep 29 14:44:27 2009
@@ -183,7 +183,7 @@
 
 ASTLocation DeclLocResolver::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
   ASTLocation ASTLoc = VisitDeclContext(TU);
-  if (ASTLoc.getDecl() == TU)
+  if (ASTLoc.getParentDecl() == TU)
     return ASTLocation();
   return ASTLoc;
 }

Modified: cfe/trunk/test/Index/resolve-loc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/resolve-loc.c?rev=83095&r1=83094&r2=83095&view=diff

==============================================================================
--- cfe/trunk/test/Index/resolve-loc.c (original)
+++ cfe/trunk/test/Index/resolve-loc.c Tue Sep 29 14:44:27 2009
@@ -26,13 +26,11 @@
 // RUN: index-test %t.ast -point-at %s:9:15 | grep for_var &&
 
 // RUN: index-test %t.ast -point-at %s:9:43 > %t &&
-// RUN: grep top_func_def %s &&
-// RUN: grep '++for_var' %s &&
+// RUN: grep '++for_var' %t &&
 
 // RUN: index-test %t.ast -point-at %s:10:9 | grep local_var2 &&
 
 // RUN: index-test %t.ast -point-at %s:10:30 > %t &&
-// RUN: grep local_var2 %t &&
 // RUN: grep 'for_var + 1' %t &&
 
 // fields test.

Modified: cfe/trunk/tools/CIndex/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=83095&r1=83094&r2=83095&view=diff

==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Tue Sep 29 14:44:27 2009
@@ -512,8 +512,8 @@
                                                                 
   ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc);
   
-  Decl *Dcl = ALoc.getDecl();
-  Stmt *Stm = ALoc.getStmt();
+  Decl *Dcl = ALoc.getParentDecl();
+  Stmt *Stm = ALoc.dyn_AsStmt();
   if (Dcl) {
     if (Stm) {
       if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Stm)) {

Modified: cfe/trunk/tools/index-test/index-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/index-test/index-test.cpp?rev=83095&r1=83094&r2=83095&view=diff

==============================================================================
--- cfe/trunk/tools/index-test/index-test.cpp (original)
+++ cfe/trunk/tools/index-test/index-test.cpp Tue Sep 29 14:44:27 2009
@@ -132,7 +132,7 @@
     Analyz.FindObjCMethods(Msg, Results);
     for (ResultsTy::iterator
            I = Results.begin(), E = Results.end(); I != E; ++I) {
-      const ObjCMethodDecl *D = cast<ObjCMethodDecl>(I->getDecl());
+      const ObjCMethodDecl *D = cast<ObjCMethodDecl>(I->AsDecl());
       if (D->isThisDeclarationADefinition())
         I->print(OS);
     }
@@ -146,7 +146,7 @@
   assert(ASTLoc.isValid());
 
   if (ObjCMessageExpr *Msg =
-        dyn_cast_or_null<ObjCMessageExpr>(ASTLoc.getStmt()))
+        dyn_cast_or_null<ObjCMessageExpr>(ASTLoc.dyn_AsStmt()))
     return ProcessObjCMessage(Msg, Idxer);
 
   Decl *D = ASTLoc.getReferencedDecl();
@@ -184,7 +184,7 @@
     Analyz.FindDeclarations(D, Results);
     for (ResultsTy::iterator
            I = Results.begin(), E = Results.end(); I != E; ++I) {
-      const Decl *D = I->getDecl();
+      const Decl *D = I->AsDecl();
       bool isDef = false;
       if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
         isDef = FD->isThisDeclarationADefinition();
@@ -285,7 +285,7 @@
       llvm::raw_ostream &OS = llvm::outs();
       ASTLoc.print(OS);
       if (const char *Comment =
-            FirstAST->getASTContext().getCommentForDecl(ASTLoc.getDecl()))
+            FirstAST->getASTContext().getCommentForDecl(ASTLoc.dyn_AsDecl()))
         OS << "Comment associated with this declaration:\n" << Comment << "\n";
     } else {
       ProcessASTLocation(ASTLoc, Idxer);





More information about the cfe-commits mailing list