diff --git a/source/api/AST/ASTVisitor.cpp b/source/api/AST/ASTVisitor.cpp index d14cece47..9e85d5927 100644 --- a/source/api/AST/ASTVisitor.cpp +++ b/source/api/AST/ASTVisitor.cpp @@ -272,8 +272,10 @@ parseParameters( { for(ParmVarDecl const* P : D->parameters()) { + // KRYSTIAN NOTE: call getOriginalType if we want to preserve + // top-level cv-qualfiers/array types/function types FieldTypeInfo& FieldInfo = I.Params.emplace_back( - getTypeInfoForType(P->getOriginalType()), + getTypeInfoForType(P->getType()), P->getNameAsString()); FieldInfo.DefaultValue = getSourceCode( D, P->getDefaultArgRange()); @@ -1292,10 +1294,17 @@ ASTVisitor:: WalkUpFromParmVarDecl( ParmVarDecl* D) { - // We do nothing here, to prevent ParmVarDecl - // from appearing as VarDecl. We pick up the - // function parameters as a group from the - // FunctionDecl instead of visiting ParmVarDecl. + Assert(shouldTraversePostOrder() && + "expected post-order traversal"); + + // apply the type adjustments specified in [dcl.fct] p5 + // to ensure that the USR of the corresponding function matches + // other declarations of the function that have parameters declared + // with different top-level cv-qualifiers + D->setType(astContext_-> + getSignatureParameterType(D->getType())); + // since we parse function parameters when we visit + // the actual function declarations, do nothing else return true; } diff --git a/source/api/AST/ASTVisitor.hpp b/source/api/AST/ASTVisitor.hpp index 4d65ae912..b933a1f43 100644 --- a/source/api/AST/ASTVisitor.hpp +++ b/source/api/AST/ASTVisitor.hpp @@ -99,6 +99,11 @@ class ASTVisitor void buildVar(VarDecl* D); public: + bool shouldTraversePostOrder() const + { + return true; + } + void HandleTranslationUnit(ASTContext& Context) override; bool WalkUpFromNamespaceDecl(NamespaceDecl* D); bool WalkUpFromCXXRecordDecl(CXXRecordDecl* D); diff --git a/test-files/old-tests/function-parm-decay.cpp b/test-files/old-tests/function-parm-decay.cpp new file mode 100644 index 000000000..459901b39 --- /dev/null +++ b/test-files/old-tests/function-parm-decay.cpp @@ -0,0 +1,24 @@ +#pragma clang diagnostic ignored "-Wdeprecated-volatile" + +void f(const int x); +void f(volatile int x); +void f(const volatile int x); +void f(int x); + +void g(int* x); +void g(int* const x); +void g(int x[]); +void g(int x[4]); + +void h(int x(bool)); +void h(int x(const bool)); +void h(int (*x)(bool)); +void h(int (*x)(const bool)); + +using T = int; +using U = const int; + +void i(T); +void i(U); +void i(const T); +void i(const U); diff --git a/test-files/old-tests/function-parm-decay.xml b/test-files/old-tests/function-parm-decay.xml new file mode 100644 index 000000000..d021707c8 --- /dev/null +++ b/test-files/old-tests/function-parm-decay.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +