From: Argyrios Kyrtzidis Date: Sat, 20 Jun 2009 08:09:14 +0000 (+0000) Subject: Introduce Decl::getSourceRange() which, like Stmt::getSourceRange(), represents the... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=55d608cbadf1e9c05064f9287c057d50b7df65b4;p=clang Introduce Decl::getSourceRange() which, like Stmt::getSourceRange(), represents the range that the declaration covers. Add initial support for NamespaceDecl, VarDecl, and FunctionDecl: -NamespaceDecl range is from name to '}' -VarDecl is from name to possible init expression -FunctionDecl is from name to last parameter name or to end of its function body. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73821 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 1f3e88fb16..77b7bf6a95 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -146,8 +146,8 @@ public: } void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; } - SourceRange getSourceRange() const { - return SourceRange(LBracLoc, RBracLoc); + virtual SourceRange getSourceRange() const { + return SourceRange(getLocation(), RBracLoc); } SourceLocation getLBracLoc() const { return LBracLoc; } @@ -259,6 +259,8 @@ public: StorageClass getStorageClass() const { return (StorageClass)SClass; } void setStorageClass(StorageClass SC) { SClass = SC; } + + virtual SourceRange getSourceRange() const; SourceLocation getTypeSpecStartLoc() const { return TypeSpecStartLoc; } void setTypeSpecStartLoc(SourceLocation SL) { @@ -644,6 +646,8 @@ private: // Move to DeclGroup when it is implemented. SourceLocation TypeSpecStartLoc; + + SourceLocation EndRangeLoc; /// \brief The template or declaration that this declaration /// describes or was instantiated from, respectively. @@ -667,7 +671,7 @@ protected: SClass(S), IsInline(isInline), C99InlineDefinition(false), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), TypeSpecStartLoc(TSSL), - TemplateOrInstantiation() {} + EndRangeLoc(L), TemplateOrInstantiation() {} virtual ~FunctionDecl() {} virtual void Destroy(ASTContext& C); @@ -677,7 +681,15 @@ public: DeclarationName N, QualType T, StorageClass S = None, bool isInline = false, bool hasWrittenPrototype = true, - SourceLocation TSStartLoc = SourceLocation()); + SourceLocation TSStartLoc = SourceLocation()); + + virtual SourceRange getSourceRange() const { + return SourceRange(getLocation(), EndRangeLoc); + } + void setLocEnd(SourceLocation E) { + assert(getLocation() <= E && "Invalid end location"); + EndRangeLoc = E; + } SourceLocation getTypeSpecStartLoc() const { return TypeSpecStartLoc; } void setTypeSpecStartLoc(SourceLocation TS) { TypeSpecStartLoc = TS; } @@ -706,7 +718,7 @@ public: /// CodeGenModule.cpp uses it, and I don't know if this would break it. bool isThisDeclarationADefinition() const { return Body; } - void setBody(Stmt *B) { Body = B; } + void setBody(Stmt *B); void setLazyBody(uint64_t Offset) { Body = Offset; } /// Whether this function is marked as virtual explicitly. diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index a2ee895256..a75eecd022 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -188,6 +188,14 @@ protected: virtual ~Decl(); public: + + /// \brief Source range that this declaration covers. + virtual SourceRange getSourceRange() const { + return SourceRange(getLocation(), getLocation()); + } + SourceLocation getLocStart() const { return getSourceRange().getBegin(); } + SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } + SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index b2b643a64f..bf63932011 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -315,6 +315,12 @@ void VarDecl::Destroy(ASTContext& C) { VarDecl::~VarDecl() { } +SourceRange VarDecl::getSourceRange() const { + if (getInit()) + return SourceRange(getLocation(), getInit()->getLocEnd()); + return SourceRange(getLocation(), getLocation()); +} + bool VarDecl::isTentativeDefinition(ASTContext &Context) const { if (!isFileVarDecl() || Context.getLangOptions().CPlusPlus) return false; @@ -371,6 +377,12 @@ Stmt *FunctionDecl::getBodyIfAvailable() const { return 0; } +void FunctionDecl::setBody(Stmt *B) { + Body = B; + if (B && EndRangeLoc < B->getLocEnd()) + EndRangeLoc = B->getLocEnd(); +} + bool FunctionDecl::isMain() const { return getDeclContext()->getLookupContext()->isTranslationUnit() && getIdentifier() && getIdentifier()->isStr("main"); @@ -481,6 +493,10 @@ void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); ParamInfo = new (Mem) ParmVarDecl*[NumParams]; memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); + + // Update source range. + if (EndRangeLoc < NewParamInfo[NumParams-1]->getLocEnd()) + EndRangeLoc = NewParamInfo[NumParams-1]->getLocEnd(); } }